Perl m// 中的 Perl 变量扩展

Perl m// 中的 Perl 变量扩展

Perl 如何在m//匹配运算符中进行变量扩展?我读到的是m//变量扩展/插值只进行一次。但是为什么我会得到Unmatched ( in regexwhen $patis 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 中的工作方式不同。)

相关内容