15

Python(2.7)で詳細な正規表現を使用しようとしています。重要なのは、いつか戻って表現をより明確に理解できるようにすることです。私は新しいので、最初にコンパクトな式を作成して、自分が望むものを確実に取得できるようにしました。

コンパクトな表現は次のとおりです。

test_verbose_item_pattern = re.compile('\n{1}\b?I[tT][eE][mM]\s+\d{1,2}\.?\(?[a-e]?\)?.*[^0-9]\n{1}')

期待どおりに動作します

これが詳細表現です

verbose_item_pattern = re.compile("""
\n{1}       #begin with a new line allow only one new line character
\b?       #allow for a word boundary the ? allows 0 or 1 word boundaries \nITEM or \n  ITEM
I        # the first word on the line must begin with a capital I
[tT][eE][mM]  #then we need one character from each of the three sets this allows for unknown case
\s+       # one or more white spaces this does allow for another \n not sure if I should change it
\d{1,2}    # require one or two digits
\.?        # there could be 0 or 1 periods after the digits 1. or 1
\(?        # there might be 0 or 1 instance of an open paren
[a-e]?      # there could be 0 or 1 instance of a letter in the range a-e
\)?         # there could be 0 or 1 instance of a closing paren
.*          #any number of unknown characters so we can have words and punctuation
[^0-9]     # by its placement I am hoping that I am stating that I do not want to allow strings that end with a number and then \n
\n{1}     #I want to cut it off at the next newline character
""",re.VERBOSE)

問題は、冗長パターンを実行すると例外が発生することです

Traceback (most recent call last):
File "C:/Users/Dropbox/directEDGAR-Code-Examples/NewItemIdentifier.py", line 17, in <module>
 """,re.VERBOSE)
 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

これはばかげたことになるのではないかと思いますが、理解できません。私は冗長な表現を取り、それを1行ずつ圧縮して、コンパクトバージョンが冗長と同じであることを確認しました。

エラーメッセージには、繰り返すものは何もないと記載されていますか?

4

2 に答える 2

18
  • 正規表現パターンを定義するときは、生の文字列リテラルを使用することをお勧めします。多くの正規表現パターンはバックスラッシュを使用します。生の文字列リテラルを使用すると、Pythonがバックスラッシュを別の意味で解釈するかどうかを心配する必要がなく、単一のバックスラッシュを記述できます(このような場合は2つのバックスラッシュを使用する必要があります)。 )。

  • \b?有効な正規表現ではありません。これは、0または1語の境界を言っています。しかし、単語の境界があるか、ないかのどちらかです。単語の境界がある場合は、1つの単語の境界があります。単語の境界がない場合は、単語の境界が0になります。したがって\b?、(有効な正規表現である場合)常に真になります。

  • 正規表現は、文字列の終わりと行の終わりを区別します。(文字列は複数の行で構成されている場合があります。)

    • \A文字列の先頭にのみ一致します。
    • \Z文字列の終わりにのみ一致します。
    • $文字列の終わりに一致し、re.MULTILINEモードでは行の終わりにも一致します。
    • ^文字列の先頭に一致し、re.MULTILINEモードの行の先頭にも一致します。

import re
verbose_item_pattern = re.compile(r"""
    $            # end of line boundary
    \s{1,2}      # 1-or-2 whitespace character, including the newline
    I            # a capital I
    [tT][eE][mM] # one character from each of the three sets this allows for unknown case
    \s+          # 1-or-more whitespaces INCLUDING newline
    \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]
    $            # end of line boundary
    """, re.VERBOSE|re.MULTILINE)

x = verbose_item_pattern.search("""
 Item 1.0(a) foo bar
""")

print(x)

収量

<_sre.SRE_Match object at 0xb76dd020>

(一致があることを示します)

于 2012-12-13T02:41:56.173 に答える
2

コメントで言うように、バックスラッシュをエスケープするか、トリプルクォートでも生の文字列を使用する必要があります。

verbose_item_pattern = re.compile(r"""
...
于 2012-12-13T02:57:59.203 に答える