【问题标题】:Python Regular Expression matching multiple lines (re.DOTALL)匹配多行的 Python 正则表达式 (re.DOTALL)
【发布时间】:2013-04-03 22:06:18
【问题描述】:

我正在尝试解析具有多行的字符串。

假设是:

text = '''
Section1
stuff belonging to section1
stuff belonging to section1
stuff belonging to section1
Section2
stuff belonging to section2
stuff belonging to section2
stuff belonging to section2
'''

我想使用 re 模块的 finditer 方法来获取字典,如:

{'section': 'Section1', 'section_data': 'stuff belonging to section1\nstuff belonging to section1\nstuff belonging to section1\n'}
{'section': 'Section2', 'section_data': 'stuff belonging to section2\nstuff belonging to section2\nstuff belonging to section2\n'}

我尝试了以下方法:

import re
re_sections=re.compile(r"(?P<section>Section\d)\s*(?P<section_data>.+)", re.DOTALL)
sections_it = re_sections.finditer(text)

for m in sections_it:
    print m.groupdict() 

但这会导致:

{'section': 'Section1', 'section_data': 'stuff belonging to section1\nstuff belonging to    section1\nstuff belonging to section1\nSection2\nstuff belonging to section2\nstuff belonging to section2\nstuff belonging to section2\n'}

所以section_data 也匹配Section2。

我还试图告诉第二组匹配除第一组以外的所有组。但这导致根本没有输出。

re_sections=re.compile(r"(?P<section>Section\d)\s+(?P<section_data>^(?P=section))", re.DOTALL)

我知道我可以使用以下 re,但我正在寻找一个版本,我不必告诉第二组是什么样子。

re_sections=re.compile(r"(?P<section>Section\d)\s+(?P<section_data>[a-z12\s]+)", re.DOTALL)

非常感谢!

【问题讨论】:

  • 您是否尝试匹配所有出现的r"(?:(?P&lt;section&gt;Section\d)\s*(?P&lt;section_data&gt;.+?))+"
  • 是的,它不起作用。输出:{'section': 'Section1', 'section_data': 's'} {'section': 'Section2', 'section_data': 's'}

标签: python regex multilinestring


【解决方案1】:

使用前瞻来匹配直到下一节标题或字符串结尾的所有内容:

re_sections=re.compile(r"(?P<section>Section\d)\s*(?P<section_data>.+?)(?=(?:Section\d|$))", re.DOTALL)

请注意,这也需要一个非贪婪的.+?,否则它仍然会一直匹配到最后。

演示:

>>> re_sections=re.compile(r"(?P<section>Section\d)\s*(?P<section_data>.+?)(?=(?:Section\d|$))", re.DOTALL)
>>> for m in re_sections.finditer(text): print m.groupdict()
... 
{'section': 'Section1', 'section_data': 'stuff belonging to section1\nstuff belonging to section1\nstuff belonging to section1\n'}
{'section': 'Section2', 'section_data': 'stuff belonging to section2\nstuff belonging to section2\nstuff belonging to section2'}

【讨论】:

  • 已经试过了,导致:{'section': 'Section1', 'section_data': 's'} {'section': 'Section2', 'section_data': 's'}跨度>
  • @user2221323:是的,我也注意到了;需要前瞻,更新答案。
  • 太棒了!这是有效的!是否可以在 re (?=(?:Section\d|$)) 的最后部分不再提及 Section\d 并使用 (?=(?:(?P=section)|$ 之类的引用))。该试验的结果与问题中的输出相同:/我查找了肯定的前瞻断言。据我了解,如果 re 在当前位置匹配并且在当前位置再次尝试整个 re 是否成功?但我不明白为什么需要 |$?
  • 不,您不能重复使用 section 匹配项,因为它只有在具有 相同的节号 时才会再次匹配,因此是完全相同的文字文本。
  • @user2221323:前瞻充当锚,如果前瞻的位置与下一个 Section\d 部分匹配,则匹配之前的文本。需要 |$ 部分来匹配文本中的 last 条目;要么有一个 next 部分,要么我们在字符串的末尾。
猜你喜欢
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多