我有一个正则表达式,其中相同的匹配条件可以应用于多个分隔符。 []
,()
和<>
都有效。例如,它看起来像这样:
\[.\]|\(.\)|<.>
有没有办法从上面的正则表达式中删除冗余?分隔符内的匹配条件始终相同,但分隔符本身可能不同。
答案 0 :(得分:1)
我猜你在问,因为
[[(<].[])>]
由于显而易见的原因,不够准确。
回答“不,没有办法”,这总是很危险,因为很难确定每个人都检查过一切。在这种情况下,人们必须经常提出可靠的证据来解答。
我不确定这是一个足够强大的证据,甚至根本不是“证据”,但请考虑这个(伪)信息理论的观点:
PCRE引擎本身不知道字符对[]
,()
和<>
之间的任何关系。因此,表达式本身必须包含该信息,即。要求至少六个字符[]()<>
才会出现。
不仅如此,但由于同样的原因,表达式本身必须定义至少两个配对(留下第三个暗示)。我不确定如何证明两个交替操作符(|
)是你能做的最好的,但我的意思是,即使 更紧凑的方式,你也会去至少保存一个 个字符,因为至少需要一位来说“配对存在!”
元字符的转义只能通过[]()
可以出现在字符类中而不被转义的事实来压缩,但首先,这并不是真正的“删除冗余”因为它是“语法中的幸运环境”,其次,你仍然需要为所述字符类的定义添加两个字符:[]
。
因此,我相信即使从理论的角度来看,如果我对正则表达式引擎无法知道的假设是正确的,那么最多可以保存 你已经提供的正则表达式中的三个字符:\[.\]|\(.\)|<.>
。
我热切期待被正则表达的大师们纠正!
答案 1 :(得分:1)
如果您真的使用PCRE library(例如通过PHP),您可以使用DEFINE组创建子例程,如下所示:
'~(?(DEFINE)(?<content>\w+))(?:<(?&content)>|\[(?&content)\]|\((?&content)\))~'
...或更可读:
(?(DEFINE)(?<content>\w+))
(?:
<(?&content)>
|
\[(?&content)\]
|
\((?&content)\)
)
这是PHP中的 demo 。它也应该在Perl中工作。