3

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

ab|a|b

?

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

一些尝试:

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

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

4

1 回答 1

6

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

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

此功能的主要目的是支持递归,但它也可以用于模式重用。

请注意,在这种情况下,您无法绕过捕获ab第一次交替,这会产生一些(可能)不必要的开销。为避免这种情况,您可以在从不执行的条件中定义组。执行此操作的规范方法是使用(?(DEFINE)...)group (检查命名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针对主题字符串(其中第一个再次是后两个的串联)。

于 2013-04-25T14:35:56.607 回答