Python正则表达式负面反向行为

时间:2016-04-23 18:14:45

标签: python regex negative-lookbehind

我试图解析一个文档,其中包含标题和子标题列表,后跟文本正文。该文件看起来像这样:

  

HEADER ONE:标题一中的一些文字。

     

HEADER TWO:标题二中的一些文字。内有更多文字   标题二。

     
      
  1. SUBHEADER INSIDE HEADER TWO:副标题二中的一些文字。
  2.   

我试图提取所有标题(但不是子标题)的列表。从上面的示例中可以看出,所有标题都由全部大写字母组成,后跟冒号。子标题以数字,句点,两个空格开头,然后是所有大写字母,后跟冒号。

这就是我现在所拥有的,但它似乎并没有起作用。它拿起所有三个HEADER ONE,HEADER TWO和SUBHEADER INSIDE HEADER TWO作为标题。我希望它只需将HEADER ONE和HEADER TWO作为两个标题:

import re

file = open('inputFile', 'r')
document = file.read()

match = re.findall('(?<!\d\.  )([A-Z ]+:)', document)

print match

当前输出:[&#39; HEADER ONE:&#39;,&#39; HEADER TWO:&#39;,&#39;内侧头部的头部说明者:&#39;] 期望的输出:[&#39; HEADER ONE:&#39;,&#39; HEADER TWO:&#39;]

我试图使用负面的外观,但似乎我做错了什么。有谁知道我做错了什么以及如何获得所需的输出?

谢谢!

2 个答案:

答案 0 :(得分:0)

你在正则表达式中缺少锚点。尝试

^(?<!\d\. )([A-Z\s]+)

<强> Regex Demo

您应该使用空格()代替\s

你也可以使用正向前瞻

^(?=[A-Z\s]+:)([A-Z\s]+)

<强> Regex Demo

<强> Ideone Demo

答案 1 :(得分:0)

  

所有标题都由全部大写字母组成,后跟冒号。

所以,你需要一个非常基本的正则表达式:

(?m)^([A-Z\s]+):

但是,它甚至可以匹配那些仅以空格和冒号开头的行。使用更精确的版本:

(?m)^([A-Z]+(?:\s+[A-Z]+)*):

请参阅regex demo

<强>解释

  • (?m) - 内联re.MULTILINE修饰符,使^行的开头匹配
  • ^ - 开始一行 - ([A-Z]+(?:\s+[A-Z]+)*) - 第1组(仅与此组匹配的值将显示在re.findall结果中)匹配
    • [A-Z]+ - 一个或多个大写字母
    • (?:\s+[A-Z]+)* - 零个或多个1+空格序列(\s+)后跟1 +大写字母[A-Z]+
  • : - 冒号

Python demo

import re
p = re.compile(r'(?m)^([A-Z]+(?:\s+[A-Z]+)*):')
s = """HEADER ONE: Some text within header one.

HEADER TWO: Some text within header two. More lines of text within header two.
    1. SUBHEADER INSIDE HEADER TWO: Some text within subheader two.
"""
res = p.findall(s)
print(res)     # => ['HEADER ONE', 'HEADER TWO']