我正在尝试扫描文档并确定文档部分的开始和结束位置。有时,文档有一个目录,其中列出了页码我不想捕获 TOC,因为它没有标识文档的一部分。一段时间以来,我一直在搞乱这个问题,并且被困在某些事情上。我似乎无法避免使用行号从目录中捕获行
这是正则表达式
verbose_item_pattern_3 = re.compile(r"""
^ # begin match at newline
\t* # 0-or-more tabspace
[ ]* # 0-or-more blank space
I # a capital I
[tT][eE][mM] # one character from each of the three sets this allows for unknown case
\t* # 0-or-more tabspace
[ ]* # 0-or-more blankspace
\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)
这是我不想捕获的一行示例
test_string='\nItem 6. TITLE ITEM 6..................................................25\n'
这是我想要捕捉的一个例子
test_string='\nItem 6. TITLE ITEM 6 maybe other words here who knows \n'
但是当我运行的时候
re.findall(verbose_item_pattern_3,test_string)
结果是
['Item 6. TITLE ITEM 6..................................................25\n']
现在对我来说有趣的是,如果我的测试字符串是这个
test_string='PART I\nItem 1. TITLE ITEM 1...................................................1\nItem 2. TITLE ITEM 2..................................................21\n'
然后用 re.findall(verbose_item_pattern_3,test_string)
结果更接近我想要的但仍然不正确
['Item 2. TITLE ITEM 2..................................................21\n']
不应该有任何捕获
最佳答案
你的正则表达式匹配是因为三件事。
- 大部分是可选的,所以很不明确
- 有一个
.*
吃掉了整行,所以你的最后一个条件[^0-9]
永远不会成立,那是因为:< - 换行符本身满足
[^0-9]
,所以[^0-9]
可以成功匹配,即使行以数字结尾。
最小的变化是在最后使用负面回顾:
verbose_item_pattern_3 = re.compile(r"""
^ # start-of-line
\t* # 0-or-more tabspace
[ ]* # 0-or-more blank space
I # a capital I
[tT][eE][mM] # one character from each of the three sets this allows for unknown case
\t* # 0-or-more tabspace
[ ]* # 0-or-more blankspace
\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
$ # end-of-line
(?<![0-9]) # NOT preceded by a decimal digit (via look-behind)
""", re.VERBOSE|re.MULTILINE)
请注意,^
和 $
实际上都不匹配换行符。它们匹配 紧接在 (^
) 或 ($
) 换行符之前的位置。换行符本身永远不是匹配的一部分。
出于这个原因,我已将他们的注释更改为更精确的 start-of-line
和 end-of-line
。
另请注意,即使在 $
之后我也可以应用负向回顾。这样做有助于防止回溯,使正则表达式更快。</p>
关于python - 当此字符串中的行尾有数字时,为什么此正则表达式不排除该行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13883257/