【问题标题】:Python extract substring via regex with marker as delimiterPython通过正则表达式提取子字符串,标记为分隔符
【发布时间】:2021-12-12 19:40:33
【问题描述】:

在文本文件中

1. Notice 
Some text 
End Notice
2. Blabla 
Some other text 
Even more text
3. Notice 
Some more text
End Notice

我想用正则表达式从“2. Blabla”和以下文本(行)中提取文本。

“2. Blabla”的部分可能在纺织品中出现多次(如“1. Notice”等)。

我试过了

pattern = r"(\d+\. Blabla[\S\n\t\v ]*?\d+\. )"
re.compile(pattern)
result = re.findall(pattern, text) 
print(result)

但它给了我

['2. BlaBla\nSome other text\nEven more text\n3. ']

我怎样才能摆脱“3.”?

【问题讨论】:

  • 您可以使用\d+\. Blabla[\S\s]*?(?=^\d+\. )。演示:regex101.com/r/VWLoMW/1
  • 实际上,(?m)^\d+\. Blabla[\S\s]*?(?=^\d+\. |\Z) 可能是更好的选择,或者 (?m)^\d+\. Blabla.*(?:\n(?!\d+\.).*)* 更快。

标签: python regex


【解决方案1】:

你可以使用

(?ms)^\d+\. Blabla.*?(?=^\d+\. |\Z)

它将匹配行首、一个或多个数字、一个点、一个空格、Blabla,然后是零个或多个字符,尽可能少,直到第一次出现一个或多个数字 + @987654327 @ + 行首或整个字符串结尾的空格。

不过,还有一个更快的表达方式:

(?m)^\d+\. Blabla.*(?:\n(?!\d+\.).*)*

请参阅regex demo详情

  • ^ - 行首(由于 Python 代码中的 re.M 选项)
  • \d+ - 一位或多位数字
  • \. - 一个点
  • Blabla - 固定字符串
  • .* - 该行的其余部分
  • (?:\n(?!\d+\.).*)* - 任何零个或多个不以一个或多个数字开头的行,然后是 . 字符。

Python demo

import re
text = "1. Notice \nSome text \nEnd Notice\n2. Blabla \nSome other text \nEven more text\n3. Notice \nSome more text\nEnd Notice"
pattern = r"^\d+\. Blabla.*(?:\n(?!\d+\.).*)*"
result = re.findall(pattern, text, re.M) 
print(result)
# => ['2. Blabla \nSome other text \nEven more text']

【讨论】:

  • 这比上面评论中给出的选项要好,因为如果“2. Blabla”块之后没有任何内容,它仍然匹配:来自评论的正则表达式不起作用:regex101.com/r/fb4W4B/1 这个工作:@ 987654324@
猜你喜欢
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多