【问题标题】:Simplifying the regex "ab|a|b"简化正则表达式“ab|a|b”
【发布时间】:2013-04-25 14:24:29
【问题描述】:

(如何)可以简化以下正则表达式:

ab|a|b

?

我正在寻找一个较少冗余的,即只有一个a 和一个b。有可能吗?

一些尝试:

a?b?       # matches empty string while shouldn't
ab?|b      # still two b

请注意,真正的正则表达式具有更复杂的 ab 部分,也就是说,不是单个字符,而是内部子正则表达式。

【问题讨论】:

  • 我的直觉告诉我不能简化
  • 您是否有理由需要简化此正则表达式?虽然有一点冗余,但仍然非常简单易读。
  • @leppie: 匹配aa和bb,都是无效的
  • @Jeff:好点,我想它不能被简化。
  • @Jeff 如您所说,该示例非常易读,但 real 正则表达式具有更复杂的 ab 部分。

标签: regex redundancy simplify


【解决方案1】:

如果您使用 Perl 或某些 PCRE 引擎(如 PHP 的 preg_ 函数),您可以参考模式中的先前组,如下所示:

/(a)(b)|(?1)|(?2)/

这个特性的主要目的是支持递归,但它也可以用于模式重用。

请注意,在这种情况下,您无法绕过在第一次交替中捕获ab,这会产生一些(可能)不必要的开销。为避免这种情况,您可以在从不执行的条件中定义组。执行此操作的规范方法是使用 (?(DEFINE)...) 组(它检查命名的 DEFINE 组是否匹配任何内容,但该组当然不存在):

/(?(DEFINE)(a)(b))(?1)(?2)|(?1)|(?2)/

如果您的引擎不支持该功能(编辑:因为您使用的是 Java,所以不支持此功能),您可以在单一模式中获得的最佳效果确实是

ab?|b

或者,您可以通过字符串连接/格式手动构建ab|a|b 版本,例如:

String a = "a";
String b = "b";
String pattern = a + b + "|" + a + "|" + b;

这也避免了重复。或者,您可以针对主题字符串使用 3 个单独的模式 abab(其中第一个模式又是后两个模式的串联)。

【讨论】:

  • @leppie 我认为这是主观的,如果你这样做,你应该使用(?:ab?) - 否则括号会通过捕获ab 导致不必要的开销(也许我应该将它添加到第一个解决方案中)
  • +1 正则表达式:你每天都能学到新东西,即使是 40 年后 ;p
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 2019-01-05
  • 2021-01-10
  • 2018-08-06
  • 1970-01-01
  • 2021-07-15
相关资源
最近更新 更多