如何巧妙地将“x”和“[x]”与正则表达式匹配而不重复?

时间:2011-06-26 16:42:38

标签: regex perl readability

我正在编写一个Perl正则表达式来匹配字符串x bla[x] bla。一种替代方案是/(?:x|\[x\]) bla/。这是不可取的,因为在现实世界中,x更复杂,所以我想避免重复它。

到目前为止,最好的解决方案是将x放入变量并预编译正则表达式:

my $x = 'x';
my $re = qr/(?:$x|\[$x\]) bla/o;

有更整洁的解决方案吗?在这种情况下,可读性比性能更重要。

5 个答案:

答案 0 :(得分:9)

这是可能的,但不是全部清洁。您可以使用条件子模式支持(?(N))等测试来检查第N个捕获子模式是否成功匹配的事实。因此,您可以使用/(\[)?X(?(1)\])/之类的表达式来匹配'[X]'或'X'。

答案 1 :(得分:1)

您也可以预编译$x。如果$x真的是?(+[*{或者正则表达式编译器会完全惹恼的其他东西,这也会使错误更加明显。

my $x = qr/x/;
my $re = qr/(?:$x|\[$x\]) bla/o;

答案 2 :(得分:1)

真的没有更简洁的解决方案,因为这是我们离开常规语言领域并开始需要更复杂的自动机与某种内存的地方。 (Backrefs会这样做,除了backref扩展到与字符串的前一部分的文字匹配,而不是“ this ,但仅当 匹配时”。 )

有时,可以改为使用两步过程,用已知在源文本中不存在的单个字符替换复杂X(控制字符可能适合于此),因此允许更简单的第二个过程阶段比赛。但并非总是可行;取决于你的匹配。

答案 3 :(得分:1)

您可以写一些类似(\[)?x(??{ defined $1 ? "]" : "" })的内容,但您可能不应该这样做。

答案 4 :(得分:1)

我测试了/(\[)?X(?(1)\])/解决方案(获得了7分),并且还匹配了[XX],这些都是错误的。原始海报/(?:$x|\[$x\]) bla/实际上有效,需要匹配括号或无。