我有一个有趣的问题,就是试图理解和改进我在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或更多限定符,则不会引发错误
我想找一些行,上面有一些不同的单词签名,作为行中的第一个单词我知道我可以用一种稍微不同的方法得到我需要的东西然而,我正在想象文档的创建者可能会将其标记为近似于单词的中心,或者他们可能会使用空格。我不想使用\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)
最佳答案
第一个字符串不是原始字符串因此,当python编译字符串时(在转到regex引擎之前),它会替换所有转义序列。因此\t
实际上将成为字符串中的制表符(而不是反斜杠-t)。但您使用的是freespacking模式(re.VERBOSE
)因此空白是无关紧要的。您的regex相当于:
^*[ ]*S[iI][gG][nN][aA][Tt][uU][rR][eE][sS]?\s*[^0-9]$
\s
即使在非原始字符串中也会保持\s
,因为它在python字符串中不是可识别的转义序列。然后就在开始处
^*
导致了问题,因为您不能重复锚定。这就是为什么您应该始终使用原始字符串来编写正则表达式然后
\t
只保留反斜杠-t,正则表达式引擎可以将其解释为一个制表符。顺便说一下,
[ ]
中的空格不是问题,因为即使在verbose/freespacing模式下,字符类中的空格也很重要。