如何在Perl中找到正则表达式匹配项的位置?
时间:2020-03-05 18:59:58 来源:igfitidea点击:
我需要编写一个接收字符串和正则表达式的函数。我需要检查是否存在匹配项,并返回匹配项的开始和结束位置。 (正则表达式已由qr //
编译。)
该函数可能还会收到"全局"标志,然后我需要返回所有匹配项的(开始,结束)对。
我不能更改正则表达式,甚至不能在其周围添加"()",因为用户可能会使用"()"和" \ 1"。也许我可以使用(?:)
。
示例:给定" ababab"和正则表达式" qr / ab /",在全局情况下,我需要取回3对(开始,结束)。
解决方案
回答
pos函数为我们提供比赛的位置。如果将正则表达式放在括号中,则可以使用" length $ 1"来获取长度(从而得出结尾)。像这样
sub match_positions { my ($regex, $string) = @_; return if not $string =~ /($regex)/; return (pos($string), pos($string) + length ); } sub all_match_positions { my ($regex, $string) = @_; my @ret; while ($string =~ /($regex)/g) { push @ret, [pos($string), pos($string) + length ]; } return @ret }
回答
如果我们希望程序中所有RE的执行速度较慢,也可以使用不推荐使用的$`变量。从perlvar:
$‘ The string preceding whatever was matched by the last successful pattern match (not counting any matches hidden within a BLOCK or eval enclosed by the current BLOCK). (Mnemonic: "`" often precedes a quoted string.) This variable is read-only. The use of this variable anywhere in a program imposes a considerable performance penalty on all regular expression matches. See "BUGS".
回答
忘记我以前的帖子,我有一个更好的主意。
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. "这些变量都是只读的,并且动态地作用于当前的块。"换句话说,如果要使用$ 1 .. $ 9,则不能使用子例程进行匹配。
回答
内置变量@ -
和@ +
分别保存最后一次成功匹配的开始和结束位置。 $-[0]和$ + [0]对应于整个模式,而$-[N]和$ + [N]对应于$ N
($ 1
,$ 2
等)子匹配。