1

質問:

Python の正規表現モジュール ( re) を使用して、一致したかどうか、または一致する可能性があるかどうかを判断するにはどうすればよいですか?

詳細:

単語の間に何があるかに関係なく、単語のパターンを正しい順序で検索する正規表現パターンが必要です。Yes見つかったMaybe場合、一致がまだ見つかった場合、または一致が見つからなかった場合に返す関数が必要Noです。パターン を探していますOne|....|Two|....|Three。ここにいくつかの例を示します (名前、その数、または順序は重要ではないことに注意してください。私が気にするのは、 と の 3 つの単語だけOneTwoありThree、その間にある許容される単語はJohnMalkovichStamosおよびTravoltaです)。

はいを返します。

One|John|Malkovich|Two|John|Stamos|Three|John|Travolta

はいを返します。

One|John|Two|John|Three|John

はいを返します。

One|Two|Three

返品可能性があります:

One|Two

返品可能性があります:

One

いいえを返します:

Three|Two|One

例が完全ではないことを理解しているので、正規表現がYESになるために私が持っているものは次のとおりです。

if re.match('One\|(John\||Malkovich\||Stamos\||Travolta\|)*Two\|(John\||Malkovich\||Stamos\||Travolta\|)*Three\|(John\||Malkovich\||Stamos\||Travolta\|)*', 'One|John|Malkovich|Two|John|Stamos|Three|John|Travolta') != None
   return 'Yes'

明らかに、パターンがThree|Two|One上記の場合は失敗し、 を返すことができますNoが、どうすればケースを確認できMaybeますか? 私はそのように括弧を入れ子にすることを考えました(注、テストされていません)

if re.match('One\|((John\||Malkovich\||Stamos\||Travolta\|)*Two(\|(John\||Malkovich\||Stamos\||Travolta\|)*Three\|(John\||Malkovich\||Stamos\||Travolta\|)*)*)*', 'One|John|Malkovich|Two|John|Stamos|Three|John|Travolta') != None
   return 'Yes'

しかし、それは私がやりたいことをするものではないと思います。

詳細:

私は実際にTravoltasandを探しているわけではありませんMalkovichs(衝撃的です、私は知っています)。、、、などのinotifyパターンと照合しIN_MOVE、それらをログに記録して何百ものものを取得し、次に入って... ....などの特定のパターンを探しますが、場合によってはそうしません' t が必要です。私は基本的に、inotify を使用して、テキスト エディターが暴走し、ファイルを変更するだけでなく一時ファイル スワップ保存を実行してプログラマーの魂を粉砕しようとしたことを検出するためのパターン マッチングを行っています。これらのログをすぐに解放したくはありませんが、必要な期間だけ保持したいと考えています。ログを消去しないことを意味します。IN_CREATEIN_OPENIN_ACCESSIN_OPENIN_MODIFYIN_DELETEIN_OPENMaybeYesは、何かを実行してからログを消去することをNo意味し、何もせずにログを消去することを意味します。プログラムごとに複数のルールがあるため(つまりvimv geditv emacs)、人間が読みやすく書きやすい正規表現を使用してから大規模なツリーを作成するか、ユーザーJoelが提案したように、ループ

4

2 に答える 2

4

これには正規表現を使用しません。しかし、それは間違いなく可能です。

regex = re.compile(
    r"""^           # Start of string
    (?:             # Match...
     (?:            # one of the following:
      One()         # One (use empty capturing group to indicate match)
     |              # or
      \1Two()       # Two if One has matched previously
     |              # or
      \1\2Three()   # Three if One and Two have matched previously
     |              # or
      John          # any of the other strings
     |              # etc.
      Malkovich
     |
      Stamos
     |
      Travolta
     )              # End of alternation
     \|?            # followed by optional separator
    )*              # any number of repeats
    $               # until the end of the string.""", 
    re.VERBOSE)

これで、一致するかどうかを確認することで、YESとMAYBEを確認できます。

>>> yes = regex.match("One|John|Malkovich|Two|John|Stamos|Three|John|Travolta")
>>> yes
<_sre.SRE_Match object at 0x0000000001F90620>
>>> maybe = regex.match("One|John|Malkovich|Two|John|Stamos")
>>> maybe
<_sre.SRE_Match object at 0x0000000001F904F0>

また、すべてのグループが試合に参加したかどうか(つまり、参加していないかどうか)を確認することで、YESとMAYBEを区別できますNone

>>> yes.groups()
('', '', '')
>>> maybe.groups()
('', '', None)

そして、正規表現がまったく一致しない場合、それはあなたにとってノーです:

>>> no = regex.match("Three|Two|One")
>>> no is None
True
于 2012-05-19T22:21:43.793 に答える
3

問題に直面したときに、「分かった、正規表現を使用する」と考える人もいます。現在、彼らには 2 つの問題があります。- ジェイミー・ザウィンスキー

おそらく、このようなアルゴリズムの方が適切でしょう。ここにいくつかの疑似コードがあります。

matchlist.current = matchlist.first()
for each word in input
    if word = matchlist.current
        matchlist.current = matchlist.next() // assuming next returns null if at end of list
    else if not allowedlist.contains(word)
        return 'No'
if matchlist.current = null // we hit the end of the list
    return 'Yes'
return 'Maybe'
于 2012-05-19T22:10:25.553 に答える