8

smileys ":)"、 ":("に一致する正規表現パターンが欲しいです。また、 ":) :)"、 ":) :("のような繰り返しのsmileysをキャプチャする必要がありますが、":("のような無効な構文を除外します。 ("。

私はこれを持っていますが、「:((」と一致します

bool( re.match("(:\()",str) ) 

私はここで明らかな何かを見逃しているかもしれません、そして私はこの一見単純なタスクのためにいくつかの助けが欲しいです。

4

4 に答える 4

8

私はそれが最終的にあなたがここで尋ねていることを正確に「クリック」したと思います。以下をご覧ください。

import re

smiley_pattern = '^(:\(|:\))+$' # matches only the smileys ":)" and ":("

def test_match(s):
    print 'Value: %s; Result: %s' % (
        s,
        'Matches!' if re.match(smiley_pattern, s) else 'Doesn\'t match.'
    )

should_match = [
    ':)',   # Single smile
    ':(',   # Single frown
    ':):)', # Two smiles
    ':(:(', # Two frowns
    ':):(', # Mix of a smile and a frown
]
should_not_match = [
    '',         # Empty string
    ':(foo',    # Extraneous characters appended
    'foo:(',    # Extraneous characters prepended
    ':( :(',    # Space between frowns
    ':( (',     # Extraneous characters and space appended
    ':(('       # Extraneous duplicate of final character appended
]

print('The following should all match:')
for x in should_match: test_match(x);

print('')   # Newline for output clarity

print('The following should all not match:')
for x in should_not_match: test_match(x);

元のコードの問題は、正規表現が間違っていることです(:\()。分解してみましょう。

外側の括弧は「グ​​ループ化」です。これらは、文字列の置換を行う場合に参照するものであり、文字のグループに正規表現演算子を一度に適用するために使用されます。だから、あなたは本当に言っています:

  • (グループを始める
    • :\(...正規表現を実行します...
  • ')'グループを終了します

:正規表現の予約文字ではないため、単なるコロンです。isであり、 「\次の文字はリテラルであり、正規表現演算子ではない」という意味です。これは「エスケープシーケンス」と呼ばれます。完全に英語に解析された、あなたの正規表現は言います

  • (グループを始める
    • :コロン文字
    • \(左括弧文字
  • )グループを終了する

私が使用した正規表現は少し複雑ですが、悪くはありません。それを分解しましょう:^(:\(|:\))+$

^$それぞれ「行の始まり」と「行の終わり」を意味します。今、私たちは...

  • ^行頭
    • (:\(|:\))+...正規表現を実行します...
  • $行の終わり

...したがって、文字列の途中で発生するのではなく、行全体を構成するものにのみ一致します。

私たちはそれを知って(おり)、グループ化を示しています。+「これらのうちの1つ」を意味します。今、私たちは持っています:

  • ^行頭
  • (グループを開始する
    • :\(|:\)...正規表現を実行します...
  • )グループを終了する
  • +これの1つ以上に一致します
  • $行の終わり

最後に、|(パイプ)演算子があります。「または」を意味します。したがって、文字のエスケープについて上から知っていることを適用して、翻訳を完了する準備ができています。

  • ^行頭
  • (グループを開始する
    • :コロン文字
    • \(左括弧文字
  • |また
    • :コロン文字
    • \)右括弧文字
  • )グループを終了する
  • +これの1つ以上に一致します
  • $行の終わり

これがお役に立てば幸いです。そうでない場合は、お知らせください。返信を添えて回答を編集させていただきます。

于 2013-02-01T18:15:11.993 に答える
3

多分次のようなものです:

re.match('[:;][)(](?![)(])', str)
于 2013-01-28T21:05:41.350 に答える
2

試してみてください(?::|;|=)(?:-)?(?:\)|\(|D|P)。広範囲にテストしていませんが、適切なものと一致しているようで、それ以上ではありません...

In [15]: import re

In [16]: s = "Just: to :)) =) test :(:-(( ():: :):) :(:( :P ;)!"

In [17]: re.findall(r'(?::|;|=)(?:-)?(?:\)|\(|D|P)',s)
Out[17]: [':)', '=)', ':(', ':-(', ':)', ':)', ':(', ':(', ':P', ';)']
于 2013-01-28T21:23:27.810 に答える
0

ここに投稿されたコメントと回答から、探していた答えが得られました。

re.match("^(:[)(])*$",str)

ありがとうございます。

于 2013-01-28T22:01:28.870 に答える