我试图解析一个文档,其中包含标题和子标题列表,后跟文本正文。该文件看起来像这样:
HEADER ONE:标题一中的一些文字。
HEADER TWO:标题二中的一些文字。内有更多文字 标题二。
- SUBHEADER INSIDE HEADER TWO:副标题二中的一些文字。
醇>
我试图提取所有标题(但不是子标题)的列表。从上面的示例中可以看出,所有标题都由全部大写字母组成,后跟冒号。子标题以数字,句点,两个空格开头,然后是所有大写字母,后跟冒号。
这就是我现在所拥有的,但它似乎并没有起作用。它拿起所有三个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;]
我试图使用负面的外观,但似乎我做错了什么。有谁知道我做错了什么以及如何获得所需的输出?
谢谢!
答案 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]+
:
- 冒号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']