正则匹配返回值和正则相关变量
Perl正则匹配返回值
正则匹配的返回值情况比较复杂,具体可参考perldoc perlop
。大致可总结为:
- 在标量上下文中,正则匹配总是在匹配成功时返回1表示布尔真,匹配失败时返回undef
- 在列表上下文中:
- 匹配失败时,总是返回空列表,表示布尔假
- 匹配成功时,如果使用了小括号分组捕获,则返回本次匹配各分组捕获的内容列表
- 匹配成功时,如果未使用小括号分组捕获,则在未使用
g
修饰符时返回列表(1)
,在使用了g
修饰符时返回全局匹配成功的内容列表
例如:
# 在标量上下文,正则匹配可直接作为判断条件
my $str = "abAB12cdCD34";
say "matched" if($str =~ /\d+/);
say "not matched" if($str =~ /xy/);
# 在列表上下文,匹配失败时,返回空列表
my @arr = $str =~ /xy/;
say ~~@arr; # 0
# 在列表上下文,匹配成功,且使用小括号分组捕获时,返回各分组内容
my @arr = $str=~/(\d+)/;
say "@arr"; # 12
@arr = $str=~/(\d+)[^0-9]+(\d+)/;
say "@arr"; # 12 34
# 在列表上下文,匹配成功,且未使用小括号分组捕获时,
# 如果未使用g修饰符全局匹配,则返回列表`(1)`
# 如果使用g修饰符全局匹配,则返回全局匹配成功的内容列表
my @arr1 = $str=~/\d+/;
say "@arr1"; # 1
my @arr2 = $str=~/\d+/g;
say "@arr2"; # 12 34
Perl正则匹配相关变量
Perl提供了一些和正则表达式相关的内置特殊变量,通过这些变量,可以访问某次正则匹配完成之后的一些数据。
例如,Perl正则匹配在标量上下文不会返回匹配成功的内容,但可以通过特殊变量$&
来获取匹配到的内容:
my $str = "abAB12cdCD34";
say "matched: $&" if($str =~ /\d+/);
下面是正则表达式相关的特殊变量总结,其中一部分在后面内容涉及到的时候还会解释。
$1 $2 $3...
保存了各个分组捕获的内容
$&
$MATCH
保存了本次匹配到的内容
$`
$PREMATCH
保存了本次匹配起始位置之前的内容
$'
$POSTMATCH
保存了本次匹配结束位置之后的内容
对于$` $& $'
,它们保存的分别是本次匹配时,匹配内容前的内容、匹配到的内容和匹配内容后的内容。例如,对于正则匹配"aAbBcC"=~/bB/
来说,匹配后它们的内容如下所示:
(aA)(bB)(cC)
| | |
$` $& $'
在以前的Perl版本中,使用$` $& $'
会有性能问题,每次匹配成功后都会拷贝对应的字符串到这三个变量中,但是从Perl v5.20开始,Perl采用了写时复制(copy-on-write)技术,只有确实使用了这些变量时,才会拷贝对应的字符串保存到这三个变量中,因此不用再担心使用这三个变量时的性能问题。
这些特殊变量是只读的,每次正则匹配时Perl会自动重置这些变量。这些变量只在当前作用域内有效,并且只在本次正则匹配后、下次正则匹配前有效。
$str = "abbc123";
$str=~/a(.*)c/;
say $1;
$str=~/a.*c/;
say $1; # undef
还有几个比较常用的特殊变量是:
$+
$LAST_PAREN_MATCH
最后一个匹配成功的分组括号所匹配的内容(PAREN是括号parentheses的缩写)
%+
%LAST_PAREN_MATCH
保存本次匹配过程中所有命名分组捕获的内容,hash的key是分组名称,value是分组捕获的内容
@-
@LAST_MATCH_START
@+
@LAST_MATCH_END
前两个数组变量保存了各个分组匹配的起始位置。后两个数组变量保存了各个分组匹配的结束位置。
@- @+
这两个变量结合substr用起来可以非常强大,通过它们可以构造出和$` $& $'
等价的值,且能构造出更多匹配结果。例如:
$` == substr($var, 0, $-[0])
$& == substr($var, $-[0], $+[0] - $-[0])
$' == substr($var, $+[0])
$1 == substr($var, $-[1], $+[1] - $-[1])
$2 == substr($var, $-[2], $+[2] - $-[2])
$3 == substr($var, $-[3], $+[3] - $-[3])