我需要编写一个接收字符串和正则表达式的函数.我需要检查是否有匹配并返回匹配的开始和结束位置.(正则表达式已经由qr//
.编译.)
该函数也可能会收到一个"全局"标志,然后我需要返回所有匹配的(开始,结束)对.
我无法更改正则表达式,甚至不能添加()
它,因为用户可能会使用()
和\1
.也许我可以用(?:)
.
例如:给出"ababab"和正则表达式qr/ab/
,在全局情况下我需要回到3对(开始,结束).
内置变量@-
并分别@+
保存上次成功匹配的开始和结束位置.$-[0]
和$+[0]
对应于整个图案,而$-[N]
与$+[N]
对应于$N
($1
,$2
等)子匹配.
忘记我以前的帖子,我有一个更好的主意.
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 }
这种技术不会以任何方式改变正则表达式.
编辑添加:引用perlvar $ 1 .. $ 9."这些变量都是只读的,并且动态地限定为当前的BLOCK." 换句话说,如果你想使用$ 1 .. $ 9,你不能使用子程序来进行匹配.
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 }