如何在Perl中找到正则表达式匹配的位置?

sza*_*gab 33 regex perl

我需要编写一个接收字符串和正则表达式的函数.我需要检查是否有匹配并返回匹配的开始和结束位置.(正则表达式已经由qr//.编译.)

该函数也可能会收到一个"全局"标志,然后我需要返回所有匹配的(开始,结束)对.

我无法更改正则表达式,甚至不能添加()它,因为用户可能会使用()\1.也许我可以用(?:).

例如:给出"ababab"和正则表达式qr/ab/,在全局情况下我需要回到3对(开始,结束).

Mic*_*man 74

内置变量@-并分别@+保存上次成功匹配的开始和结束位置.$-[0]$+[0]对应于整个图案,而$-[N]$+[N]对应于$N($1,$2等)子匹配.

  • 这些神奇的变量让我想要来自Python; 在[perl re docs](http://perldoc.perl.org/perlre.html)中,它们甚至没有被引用过一次. (12认同)
  • perldoc perlvar ;-) (5认同)
  • 请注意,$ + [0]等("结束位置")给出*匹配后的字符*的索引,而不是匹配本身的最后一个字符. (4认同)

Leo*_*ans 19

忘记我以前的帖子,我有一个更好的主意.

sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /$regex/;
    return ($-[0], $+[0]);
}
sub match_all_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /$regex/g) {
        push @ret, [ $-[0], $+[0] ];
    }
    return @ret
}
Run Code Online (Sandbox Code Playgroud)

这种技术不会以任何方式改变正则表达式.

编辑添加:引用perlvar $ 1 .. $ 9."这些变量都是只读的,并且动态地限定为当前的BLOCK." 换句话说,如果你想使用$ 1 .. $ 9,你不能使用子程序来进行匹配.


Leo*_*ans 10

pos函数为您提供匹配的位置.如果将正则表达式放在括号中,则可以使用长度(因此结束)length $1.像这样

sub match_positions {
    my ($regex, $string) = @_;
    return if not $string =~ /($regex)/;
    return (pos($string), pos($string) + length $1);
}
sub all_match_positions {
    my ($regex, $string) = @_;
    my @ret;
    while ($string =~ /($regex)/g) {
        push @ret, [pos($string), pos($string) + length $1];
    }
    return @ret
}
Run Code Online (Sandbox Code Playgroud)

  • 这看起来完全不正确。而不是 pos ,在 all_match_positions 中使用 pos($string) ,在另一种情况下, match_positions 它根本不起作用 (3认同)