Codegolf正则表达式匹配

时间:2014-07-12 19:44:43

标签: regex perl

在codegold中,我找到了这个答案:https://codegolf.stackexchange.com/a/34345/29143,这是perl one liner:

perl -e '(q x x x 10) =~ /(?{ print "hello\n" })(?!)/;'

-MO = Deparse得到后:

'          ' =~ /(?{ print "hello\n" })(?!)/;
^^^^^^^^^^^^
10 spaces

说明的解释比(?!)从不匹配,所以正则表达式尝试匹配每个字符。好的,但为什么它打印11次你好而不是10次?

3 个答案:

答案 0 :(得分:2)

这是因为当你有一串n个字符时,在测试模式的字符串中有n + 1个位置。

"abc"的例子:

  a b c 
 ^ ^ ^ ^
 | | | |
 | | | +--- end of the string
 | | +----- position of c
 | +------- position of b
 +--------- position of a 

字符串结尾的位置可能有点违反直觉,但这个位置存在。为了说明这一事实,请考虑使用示例字符串成功的模式/c$/(考虑结束锚点测试时字符串中的位置)。或者在最后一个位置成功的另一个/(?<=c)/

答案 1 :(得分:2)

看看以下内容:

$x = "abc"; $x =~ s/.{0}/x/; print("$x\n");  # xabc
$x = "abc"; $x =~ s/.{1}/x/; print("$x\n");  # xbc
$x = "abc"; $x =~ s/.{2}/x/; print("$x\n");  # xc
$x = "abc"; $x =~ s/.{3}/x/; print("$x\n");  # x

没什么好奇怪的。您可以匹配三个字符中0到3之间的任意位置,并将x放在您离开的位置。这是三个角色的四个位置。


另请考虑'abc' =~ /^abc\z/

  • 从位置0开始,^匹配零字符。
  • 从位置0开始,a匹配一个字符。
  • 从位置1开始,b匹配一个字符。
  • 从位置2开始,c匹配一个字符。
  • 从位置3开始,\z匹配零字符。

同样,这是三个字符串所需的总共四个位置。

只有零宽度断言可以在最后一个位置匹配,但有很多断言(^\z\b(?=...),{{1} },(?!...)(?<=...)等。)


如果有帮助,您可以将这些位置视为角色的边缘。

(?:...)?

答案 2 :(得分:2)

正则表达式基于关闭位置开始匹配,其可以包括在每个字符之前,也包括在最后一个字符之后。

以下零宽度正则表达式将在字符串的5个字符中的每个字符之前匹配,但也在最后一个字符之后匹配,从而说明为什么您有11个打印而不是10个。

use strict;
use warnings;

my $string = 'ABCDE';

# Zero width Regular expression
$string =~ s//x/g;

print $string;

输出:

xAxBxCxDxEx
^ ^ ^ ^ ^ ^
1 2 3 4 5 6