Perl 如何在m//
匹配运算符中进行变量扩展?我读到的是m//
变量扩展/插值只进行一次。但是为什么我会得到Unmatched ( in regex
when $pat
is Expanded 呢?
my $pat = '(\\)';
'\\' =~ /(\\)/ ? print "OK\n" : print "NO MATCH!\n"; # OK
'\\' =~ /$pat/ ? print "OK\n" : print "NO MATCH!\n"; # Unmatched ( in regex
my $pat2 = '(\\\)';
'\\' =~ /$pat2/ ? print "OK\n" : print "NO MATCH!\n"; # OK
答案1
您的问题是您错误地应用或错误地记住了有关反斜杠的神秘规则。
在一个单引号字符串文字,
反斜杠表示反斜杠,除非后跟分隔符或另一个反斜杠,在这种情况下,分隔符或反斜杠将被插入。
所以 的值$pat
是三字符字符串(\)
,因为源代码中的反斜杠后面跟着另一个反斜杠,这代表单个反斜杠。的值$pat2
是四字符的字符串(\\)
,因为源代码中的前两个反斜杠代表一个反斜杠,第三个反斜杠后面跟着,)
所以它单独作为字符串中的第二个反斜杠。
在一个正则表达式,反斜杠引用下一个字符,除非它是字母数字。/$pat/
相当于/(\)/
,它是开组,后跟一个文字右括号,并且)
缺少关闭该组的 。/$pat2/
相当于/(\\)/
which 是开组、反斜杠、闭组。
答案2
当您分配给 时$pat
,第一个反斜杠会对第二个反斜杠进行转义,因此生成的字符串仅包含一个反斜杠。当处理正则表达式时,它会转义右括号,不留下未转义的括号来关闭捕获组。
也就是说,m//
只解释一次反斜杠,但它们也在 内解释'...'
,所以总共处理了两次。
$ cat p.pl
$pat = '(\\)'; print $pat
$ perl -l p.pl
(\)
来自手动的:
类引号运算符
q/STRING/
'STRING'
单引号的文字字符串。反斜杠表示反斜杠,除非后跟分隔符或另一个反斜杠,在这种情况下,分隔符或反斜杠将被插入。
(当然,这与反斜杠和单引号在 shell 中的工作方式不同。)