我的文档中有一些用标题很好地表示的部分。我想用这些标题把文件分成几个部分。示例:
1.1 Lorem Ipsum
Blah blah blah
9 (page break, never will have a period in it though)
Bleh bleh bleh as referenced in Section 1.3 hey hey hey
1.2 Lorem Ipsumus
Blah blah blah
我想要一个正则表达式,可以采取标题和文本,直到下一个标题出现。所以这个例子的期望结果是
^{pr2}$以及
1.2 Lorem Ipsumus Blah blah blah
有一件事我总是可以指望的是,部分标题将是一个新的行,以某种数字x.x开头,后面跟着几个单词,因为这是标题的独特之处,所以我想搜索它。在
基本上,如果我看到一个新的行,形式是“1.2节定义”,我知道这是一个新的部分,我想从那里抓取所有的文本,直到下一行以“1.3节示例”或“2.1节术语”开头。章节标题总是以新行开头,格式为“第1.3节示例”、“第1.3条示例”或“1.3示例”。在
有时在一行中间会提到标题,我想忽略这些。这可以在示例中看到。在
有人知道怎么做吗?最好是在python中,但是如果regex不足够的话,那么regex就足够了。在
p.s.是否保留页码是可选的,但是regex最好不会基于页码创建新的部分
编辑:到目前为止,这是我运行的MWE。不完全在那里。在
import re
doc_splitter = re.compile(r"(?<=\n)(?P<secname>[\w]+ )(\d+\.\d+ .*?)(?<=\n)(?P<secname2>[\w]+ )(?=\d+\.\d+|\Z)", re.DOTALL)
text = """
Section 1.1 Lorem Ipsum
Blah blah blah
9
Bleh bleh bleh Section 1.1 hey hey hey
Section 1.2 Lorem Ipsumus
ref Section 1.3
Blah blah blah
Section 1.3 hey hey
Section 1.4
"""
for match in doc_splitter.finditer(text):
print([match.group()])
理想情况下,它会返回:
['Section 1.1 Lorem Ipsum Blah blah blah 9 Bleh bleh bleh Section 1.1 hey hey hey']
['Section 1.2 Lorem Ipsumus ref Section 1.3 Blah blah blah']
['Section 1.3 hey hey']
['Section 1.4']
但它却返回:
['Section 1.1 Lorem Ipsum\n\nBlah blah blah\n9\nBleh bleh bleh Section 1.1 hey hey hey\n\nSection ']
['Section 1.3 hey hey\n\nSection ']
谢谢大家的帮助!如果有人对如何解决最后一个问题有任何想法,我们将不胜感激。在
您要查找的正则表达式可能类似于:
,在给定python代码的情况下,可以使用
^{pr2}$finditer
在整个文档上运行:印刷品:
这似乎是你想要的。在
如果您以不同的方式迭代数据,您可能能够摆脱繁琐的lookaround断言,这些断言可能无法清晰地转换为其他需要恒定长度lookaround的语言。核心使用
(\d+\.\d+ .*?)
并强制执行完全匹配。在替代方案
Jan的回答是好的,但我还想添加一个解决方案,在没有前瞻性条件的情况下解决问题,因为它们看起来是多余的:
印刷品:
regex只搜索新部分的开始部分,并且应该易于维护和扩展。我们必须通过另外一个步骤,从每个新的开始手工拆分
text
,这是前一部分的结尾。在虽然regex完全可以在一个步骤中处理这种匹配,但我个人更希望它们尽可能短。它们已经够难理解了。在
你可以用我的两分钱
使用
verbose
和multiline
修饰符,请参见a demo on regex101.com。在
Python
中: ^{pr2}$我建议您尝试regex101.com,它将帮助您可视化您的正则表达式。另外,documentation for re对于学习(或记住)特殊字符是如何工作的非常有用。在
在您的示例中,我将使用以下regex(带命名组):
分解:
对于节号和标题,我使用了以空格分隔的命名组}。在
(?P<section_number>\d\.\d)
和{主体
(?P<body>.+?)
后面是正展望(?=\d\.\d[\w ]+|$)
。这意味着当另一节即将开始或文档结束时,它将停止捕获文本。它必须是nongreedy(+?
),否则您只需要打开一个部分,将文档的其余部分作为主体。在注意:在编译或搜索匹配项时,需要启用
re.DOTALL
,否则该点将与新行字符不匹配。在如果希望节标题与字符串的begging匹配,也可以在lookahead中添加一个
^{pr2}$^
,但是需要启用re.MULTILINE
。您还必须将末尾的$
改为\Z
,这样它只匹配文档的结尾,而不是每行的结尾。在相关问题 更多 >
编程相关推荐