【问题标题】:Python regex negative lookbehind behaviourPython 正则表达式负后向行为
【发布时间】:2016-04-23 18:14:44
【问题描述】:

我正在尝试解析包含标题和子标题列表的文档,然后是正文。该文件看起来像这样:

标题一:标题一中的一些文本。

标题二:标题二中的一些文本。内有更多的文本行 标题二。

  1. 标题 2 内的子标题:副标题 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

当前输出:['HEADER ONE:', 'HEADER TWO:', 'SUBHEADER INSIDE HEADER TWO:'] 期望的输出:['HEADER ONE:', 'HEADER 2:']

我尝试使用否定的lookbehind,但似乎我做错了什么。有谁知道我做错了什么以及如何获得所需的输出?

谢谢!

【问题讨论】:

  • 我认为在这种情况下,逐行处理文件并检查每一行可能会更容易。如果该行以空格开头,您就知道它不能是标题。

标签: python regex negative-lookbehind


【解决方案1】:

您的正则表达式中缺少锚点。试试

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

Regex Demo

你应该使用空格()而不是\s

您也可以使用积极的前瞻作为

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

Regex Demo

Ideone Demo

【讨论】:

  • @WiktorStribiżew 说实话,我只是想在这里坚持 OP 的格式..虽然我应该包括那些
  • 谢谢,但我不使用锚点的原因是因为我使用的是file.read(),它会一次读取整个文件,所以正则表达式适用于所有文件中的文本,而不是每次的每一行。考虑到这一点,您知道为什么我的正则表达式不排除子标题吗?感谢您的回复。
  • @Wiktor Stribiżew,哦等等,没关系,请忽略我的最后评论。我没有看到您添加到正则表达式的修饰符,这使它起作用。谢谢!
【解决方案2】:

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

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

(?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]+ - 1 个或多个大写字母
    • (?:\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']

【讨论】:

    猜你喜欢
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    相关资源
    最近更新 更多