【问题标题】:How to combine regex lookaround expressions如何组合正则表达式环视表达式
【发布时间】:2016-01-25 08:38:55
【问题描述】:

对于这个示例文本:

快速棕色狐狸跳过懒狗”是一个 1*** 英语 2*** pangram - 一个包含所有字母的短语。它通常用于触摸打字练习。它还用于测试打字机和电脑键盘、显示字体和其他涉及 3*** 英文字母 4*** 中所有字母的应用程序。

我需要一个正则表达式来匹配许多 x*** 标记,同时去除前导和尾随空格。如果我对正则表达式的有限了解是正确的,那么结果应该匹配到两个单独的环视组。

英语

英文字母

我有两个单独使用但不能同时使用的表达式:

(?<=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}
  • 你想达到什么目的?得到一个匹配一个或另一个的正则表达式?或者获取一个正则表达式,其中一组的匹配是English-language,而另一组的匹配是English alphabet
  • 我认为对于这个例子,我需要分成两组。问题是我正在使用专有前端来匹配使用正则表达式的命名“令牌”变量匹配的正则表达式。如果匹配,命名变量可用于创建重新格式化的输出。我认为这些变量后面使用了组。
  • @ndn 我有不同的文本,我需要在其中匹配开始和结束标记。实际上,可以有许多(超过两个)部分要匹配,每个部分都带有标记对。我可以控制令牌,所以我选择递增令牌可能不是最好的。我很确定我需要环视来排除实际的标记,但我的尝试只返回最后一个匹配项。

标签: regex token regex-lookarounds


【解决方案1】:
(?<=[1-9]\*\*\*)\s*(.*?)(?=\s*[1-9]\*\*\*)

您可以使用它并获取group 1。查看演示。

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

如果你只想要2 匹配使用

(?<=[13]\*\*\*)\s*(.*?)(?=\s*[24]\*\*\*)

【讨论】:

  • 哇,regex101 太棒了!
  • @SPB 然后使用(?&lt;=[13]\*\*\*)\s*(.*?)(?=\s*[24]\*\*\*)
  • 对不起,我应该在我的示例中使用两个以上的匹配项。假设这个表达式匹配到三组,我只需要两组,那么对于八个需要的组,我需要组 1、3、5、7、9、11、13 和 15。
【解决方案2】:

如果您想要一个匹配其中一个或另一个的正则表达式,您可以使用交替 (|):

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

See it in action


如果您想要一个在单独的组中同时匹配两者的正则表达式,您可以在两者之间使用 .*? 并将它们放入匹配的组中 (()):

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

See it in action

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多