首页 > 解决方案 > 如何让正则表达式在 B 的最大匹配次数后停止搜索 A

问题描述

我正在尝试使用 Python re 库在一组行中搜索关键字 A。组中的行数在 3 到 5 的范围内。每行用“
”和“”括起来。关键字 A 可能出现在组中,也可能不出现。如果没有,我希望它对我来说没有。文本示例如下所示:

<BR>GROUP #1</BR>
<BR>arbitrary characters 1</BR>
<BR>arbitrary characters 2</BR>
<BR>arbitrary characters 3</BR>
<BR>GROUP #2</BR>
<BR>arbitrary characters 4</BR>
<BR>arbitrary characters 5</BR>
<BR>KEYWORD_A_2</BR>
<BR>Group #3</BR>
<BR>arbitrary characters 6</BR>
<BR>arbitrary characters 7</BR>
<BR>arbitrary characters 8</BR>
<BR>KEYWORD_A_3</BR>
....

(注意:大写字符可能是关键字,应与原文完全相同。)

我的第一次尝试,'<BR>Group #(\d+)</BR>.*?<BR>Keyword_A_(\d+)</BR>'显然可能会越过组的边界并得到 (1, 2) 的匹配,而不是我希望的 (1, None)。

我的下一个尝试是'<BR>Group #(\d+)</BR>(?:<BR>.*?</BR>){,3}<BR>Keyword_A_(\d+)</BR>'将 .. 对限制
为 3。但这将是一个贪婪的匹配,以便匹配 'KEYWORD_A_3' 并返回 (1, 3)。

因此,总而言之,我试图让正则表达式在匹配“GROUP #(\d+)”后最多 5 行后找到“KEYWORD_A_(\d+)”。如果超过 5 行没有匹配,则停止搜索,返回 None,并将正则表达式的当前位置设置在 'GROUP #(\d+)' 匹配的末尾,这样我就可以开始在下一个组中搜索。

这可能与 Python 的 re 库有关吗?感谢您的帮助。

标签: pythonregex

解决方案


您可以使用

re.findall(r'<BR>Group\s+#(\d+)</BR>((?:(?!<BR>Group\s+#\d).)*?)<BR>Keyword_A_(\d+)</BR>', text, re.DOTALL)

查看正则表达式演示

细节

  • <BR>Group- 文字<BR>Group字符串
  • \s+- 1+ 空格
  • #- 一个#字符
  • (\d+)- 捕获组 1:一位或多位数字
  • </BR>- 一个子串
  • ((?:(?!<BR>Group\s+#\d).)*?)- 捕获组 2:任何字符,0 或更多但尽可能少的不启动<BR>Group\s+#\d模式的出现
  • <BR>Keyword_A_ - 文字子串
  • (\d+)- 捕获组 3:一位或多位数字
  • </BR>- 一个子串

推荐阅读