3

PythonでのREGEXの使用を理解し、改善しようとすると、興味深い問題が発生します。

これが正規表現です

verbose_signature_pattern_2 = re.compile("""
^            # begin match at new line
\t*          # 0-or-more tab
[ ]*         # 0-or-more blankspaces
S            # capital S
[iI][gG][nN][aA][Tt][uU][rR][eE]
[sS]?        # 0-or-1 S
\s*          # 0-or-more whitespace
[^0-9]       # anything but [0-9]
$            # newline character
""", re.VERBOSE|re.MULTILINE)

コードを実行するとエラーが発生します

""", re.VERBOSE|re.MULTILINE)
  File "C:\Python27\lib\re.py", line 190, in compile
return _compile(pattern, flags)
File "C:\Python27\lib\re.py", line 242, in _compile
raise error, v # invalid expression
error: nothing to repeat

タブ(\ t)特殊文字の0以上の修飾子を削除しても、エラーはスローされません。

Iiは、行の最初の単語として、Signatureという単語の変形が含まれている行を見つけようとしています。私は少し異なるアプローチを使用して、必要なものを手に入れることができることを知っています。ただし、ドキュメントの作成者がタブで単語のほぼ中央に移動したり、スペースを使用したりする可能性があることを想像しています。署名という単語が含まれる行の前にある可能性のある空の行をすべてキャプチャしたくないため、\sは使用しません。具体的には、私はこのすべてのクラッドをキャプチャすることを避けようとしています

'\n\n\n\n            Signature    \n

これを出力で見たいだけです

'            Signature    \n

余分な改行文字を簡単に取り除くことができることはわかっていますが、より正確に理解して実行しようとしています。興味深いのは、次のREGEXの開始は同じですが、期待どおりに機能しているように見えることです。つまり、これをコンパイルしてもエラーは発生せず、必要なものが得られているようですが、さらにいくつかのエッジケースを見つける必要があります。

verbose_item_pattern_2 = re.compile(r"""
^            # begin match at newline
\t*          # 0-or-more tabs
[ ]*         # 0-or-more blanks
I            # a capital I
[tT][eE][mM] # one character from each of the three sets this allows for unknown case
\t*          # 0-or-more tabs
[ ]*         # 0-or-more blanks
\d{1,2}      # 1-or-2 digits
[.]?         # 0-or-1 literal .
\(?          # 0-or-1 literal open paren
[a-e]?       # 0-or-1 letter in the range a-e
\)?          # 0-or-1 closing paren
.*           # any number of unknown characters so we can have words and punctuation
[^0-9]       # anything but [0-9]
$            # 1 newline character
""", re.VERBOSE|re.MULTILINE)
4

1 に答える 1

7

最初の文字列は生の文字列ではありません。したがって、Pythonが文字列をコンパイルすると(正規表現エンジンに送られる前に)、すべてのエスケープシーケンスが置き換えられます。したがって\t、実際には文字列のタブ文字になります(バックスラッシュ-tではありません)。ただし、フリースペースモード(re.VERBOSE)を使用しています。したがって、空白は重要ではありません。正規表現は次のものと同等です。

^*[ ]*S[iI][gG][nN][aA][Tt][uU][rR][eE][sS]?\s*[^0-9]$

\sPython\s文字列では認識されたエスケープシーケンスではないため、生の文字列以外の文字列でもそのままです。

次に^*、アンカーを繰り返すことができないため、最初から問題が発生しています。

これが、正規表現を書くために常に生の文字列を使用する必要がある理由です。その後\t、バックスラッシュtのままで、正規表現エンジンはそれをタブとして解釈できます。

[ ]ちなみに、冗長/フリースペースモードでも、文字クラスのスペースは重要であるため、のスペースは問題になりません。

于 2012-12-13T17:42:16.460 に答える