如何组合正则表达式的环视表达式

4

针对此示例文本:

"The quick brown fox jumps over the lazy dog"是一句包含英语字母表中所有字母的1*** 英语平板词组。它通常用于打字练习。它还用于测试打字机和计算机键盘、显示字体以及其他涉及英语字母表中所有字母的应用程序4***。

我需要一个正则表达式,可以匹配在多个 x*** 标记之间,并剥离前导和尾随空格。如果我的正则表达式知识有限,则结果应该能够匹配成两个单独的“lookaround”组。

English-language

English alphabet

我有两个表达式分别单独运行时可用,但合并后不起作用:

(?<=1\*\*\*\s).*(?=\s2\*\*\*)
....
(?<=3\*\*\*\s).*(?=\s4\*\*\*)

我试过各种方法将它们合并成一个表达式,但只得到了不正确的结果。例如:

(?<=1\*\*\*\s).*(?=\s2\*\*\*)\w+(?<=3\*\*\*\s).*(?=\s4\*\*\*)

没有匹配项

需要指出的是,我对令牌格式有控制权,因此请自由推荐一个基于正则表达式易于使用的格式。它只需要包含大部分非字母数字字符序列,以便在数据中不存在本地找到。 我猜我可能需要至少两个令牌;一个开始,一个结束。

编辑: 我已经取得了一些进展,但我的正则表达式引擎的行为与regex101上的不同:

(?<=1\*\*\*\s)(.*)(?=\s2\*\*\*).*?(?<=3\*\*\*\s)(.*)(?=\s4\*\*\*)

结果是:

英文 2*** 3*** 英文

为什么会这样? 如何纠正?


听起来你只需要一个带有懒惰点匹配的捕获组:\d+\*{3}\s*(.*?)\s*\d+\*{3} - Wiktor Stribiżew
你想要实现什么?获得一个匹配其中之一的正则表达式吗?还是获得一个正则表达式,其中一个组的匹配是“英语语言”,另一个组的匹配是“英文字母”? - ndnenkov
我认为对于这个例子我需要它分成两组。问题是我正在使用一个专有的正则表达式前端,该前端使用命名的“标记”变量来匹配正则表达式。当匹配成功时,这些命名变量可以用于创建重新格式化的输出。我推测在这些变量后面使用了组。 - SPB
你能否像这样写一个正则表达式:[(?s)\d+\*{3}\s*(?<g1>.*?)\s*\d+\*{3}.*?\d+\*{3}\s*(?<g2>.*?)\s*\d+\*{3}],并使用g1g2组? - Wiktor Stribiżew
@ndn 我有许多不同的文本需要在起始和结束标记之间匹配。实际上,可能有许多(超过两个)要匹配的部分,每个部分都有一对标记。我控制标记,因此我的增量标记选择可能不是最好的。我相当确定我需要使用环视来排除实际标记,但我的尝试只返回最后一个匹配。 - SPB
2个回答

1
如果你想要一个能够匹配其中一个的正则表达式,你可以使用替换符号 (|):
(?<=1\*\*\*\s).*(?=\s2\*\*\*)|(?<=3\*\*\*\s).*(?=\s4\*\*\*)

在这里查看它的运行情况


如果您想要一个正则表达式可以同时匹配并分别放在不同的组中,您可以在两个目标之间使用.*?,然后将它们放在匹配的组中(())。
(?<=1\*\*\*\s)(.*)(?=\s2\*\*\*).*?(?<=3\*\*\*\s)(.*)(?=\s4\*\*\*)

在操作中查看


1
(?<=[1-9]\*\*\*)\s*(.*?)(?=\s*[1-9]\*\*\*)

您可以使用这个并抓取第1组。请参见演示。

https://regex101.com/r/cZ0sD2/9

如果你只想要2个匹配,使用以下代码。
(?<=[13]\*\*\*)\s*(.*?)(?=\s*[24]\*\*\*)

哇,那个regex101太棒了! - SPB
@SPB 然后使用 (?<=[13]\*\*\*)\s*(.*?)(?=\s*[24]\*\*\*) - vks
抱歉,我在示例中应该使用超过两个匹配项。假设此表达式匹配为三组,而我只需要其中两组,则对于需要八组的情况,我需要使用第1、3、5、7、9、11、13和15组。 - SPB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接