Oniguruma正则表达式引擎中的命名子程序?

3
在Perl中,你可以这样做:
(?x)
(?(DEFINE)
  (?<animal>dog|cat)
)
(?&animal)

在 Ruby(Oniguruma 引擎)中似乎不支持 (?(DEFINE... 语法。而且,(?&... 变成了 \g。因此,你可以这样做:
(?x)
(?<animal>dog|cat)
\g<animal>

当然,这与我上面提到的Perl示例不等价,因为第一个(?<animal>dog|cat)不会被忽略,因为没有类似于(?(DEFINE...的东西。
如果我想定义一个带有大量命名子程序的大型正则表达式,我曾经在Perl中所做的事情无法以这种方式完成。
看起来我可以通过像这样的方式拼凑出一个非常尴尬的解决方案:
(?x)
(?:^$DEFINE
  (?<animal>dog|cat)
){0}
\g<animal>

但是,那样做相当不专业。有没有更好的方法?Oniguruma是否支持一种定义命名子程序的方式,而无需先尝试“匹配”它们?

或者,如果有一种方法可以让真正的PCRE在Ruby中工作,带有?(DEFINE...(?&...,我也会选择这种方法。

谢谢!

1个回答

6
您不需要如此复杂的黑客技巧。只需编写以下内容即可:
(?x)
(?<animal>dog|cat){0}
(?<color>red|green|blue){0}
...
your main pattern here

这完全相同。

将所有组定义放在 (?:^$DEFINE ... ){0} 中仅是为了美观。

请注意,带有量词 {0} 的组根本不会被尝试(首先考虑量词),如果以这种方式定义了命名组,人们可以推断出它并不是一种hack,而是使用oniguruma的方法。


2
好的回答,但我想补充一点,“修饰性”的形式应该只是 (?: ... ){0}^$DEFINE 部分没有任何作用,如果变量 $DEFINE 已经被设置,它的值可能会破坏正则表达式。正如你所说,{0} 提供了基本的功能;分组只是方便之举。 - Alan Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接