使用多个可能的分隔符从正则表达式中删除冗余

时间:2012-10-05 00:47:13

标签: regex pcre

我有一个正则表达式,其中相同的匹配条件可以应用于多个分隔符。 []()<>都有效。例如,它看起来像这样:

\[.\]|\(.\)|<.>

有没有办法从上面的正则表达式中删除冗余?分隔符内的匹配条件始终相同,但分隔符本身可能不同。

2 个答案:

答案 0 :(得分:1)

我猜你在问,因为

[[(<].[])>]
由于显而易见的原因,

不够准确。

回答“不,没有办法”,这总是很危险,因为很难确定每个人都检查过一切。在这种情况下,人们必须经常提出可靠的证据来解答。

我不确定这是一个足够强大的证据,甚至根本不是“证据”,但请考虑这个(伪)信息理论的观点:

  1. PCRE引擎本身不知道字符对[]()<>之间的任何关系。因此,表达式本身必须包含该信息,即。要求至少六个字符[]()<>才会出现。

  2. 不仅如此,但由于同样的原因,表达式本身必须定义至少两个配对(留下第三个暗示)。我不确定如何证明两个交替操作符(|)是你能做的最好的,但我的意思是,即使 更紧凑的方式,你也会去至少保存一个 个字符,因为至少需要一位来说“配对存在!”

  3. 元字符的转义只能通过[]()可以出现在字符类中而不被转义的事实来压缩,但首先,这并不是真正的“删除冗余”因为它是“语法中的幸运环境”,其次,你仍然需要为所述字符类的定义添加两个字符:[]

  4. 因此,我相信即使从理论的角度来看,如果我对正则表达式引擎无法知道的假设是正确的,那么最多可以保存 你已经提供的正则表达式中的三个字符:\[.\]|\(.\)|<.>

  5. 我热切期待被正则表达的大师们纠正!

答案 1 :(得分:1)

如果您真的使用PCRE library(例如通过PHP),您可以使用DEFINE组创建子例程,如下所示:

'~(?(DEFINE)(?<content>\w+))(?:<(?&content)>|\[(?&content)\]|\((?&content)\))~'

...或更可读:

(?(DEFINE)(?<content>\w+))
(?:
  <(?&content)>
  |
  \[(?&content)\]
  |
  \((?&content)\)
)

这是PHP中的 demo 。它也应该在Perl中工作。