为啥 q/\\a/ 等于 q/\a/?
Posted
技术标签:
【中文标题】为啥 q/\\\\a/ 等于 q/\\a/?【英文标题】:Why does q/\\a/ equal q/\a/?为什么 q/\\a/ 等于 q/\a/? 【发布时间】:2016-12-12 17:50:55 【问题描述】:以下示例打印“SAME”:
if (q/\\a/ eq q/\a/)
print "SAME\n";
else
print "DIFFERENT\n";
我了解这与documentation 一致。但我认为这种行为是不可取的。是否需要在单引号字符串中避免反冲 lilteral ?如果我想要 2 次反冲,我需要指定 4;这似乎不太方便。
Perl 不应该检测反斜杠是否用作转义字符吗?例如,当反斜杠不在分隔符之前时,它应该被视为文字;如果是这样的话,我不需要 3 个反斜杠来表达两个,例如,
q<a\\b>
而不是
q<a\\\b>.
【问题讨论】:
尝试使用q/\/
,您会发现需要转义反斜杠。
对不起,我最初的问题并不完全清楚。我添加了单词“literal”来强调反斜杠不能用作转义字符的事实。您的示例没有反映我的问题,因为在您的情况下,根据定义,分隔符之前的反斜杠充当转义字符。
"当反斜杠不在分隔符之前,它应该被视为文字" 那么如何创建以反斜杠结尾的字符串呢? q/\/
-> 文字斜线,没有结束分隔符(语法错误); q/\\/
-> 文字反斜杠,文字斜杠,没有结束分隔符(语法错误); q/\\\/
-> 文字反斜杠、文字反斜杠、文字斜杠、没有结束分隔符(语法错误); ...
"...如何创建以反斜杠结尾的字符串?" --- 一个优秀的用例!由于它 确实 在(关闭)分隔符之前,因此不应将其视为文字,因此需要对其进行转义。除了这个用例之外,我认为我的建议会在内部任何地方出现反冲而不是紧挨定界符时起作用。
除非你知道结束分隔符在哪里,否则你不能从结束分隔符向后走。
【参考方案1】:
是否需要避免单引号字符串中的反冲?
是的,如果反斜杠后面跟着另一个反斜杠,或者是字符串中的最后一个字符:
$ perl -e'print q/C:\/'
Can't find string terminator "/" anywhere before EOF at -e line 1.
$ perl -e'print q/C:\\/'
C:\
这使得可以在单引号字符串中包含任何字符,包括分隔符和转义字符。
如果我想要 2 个反冲,我需要指定 4;这似乎不太方便。
实际上,您只需要三个(因为第二个反斜杠后面没有另一个反斜杠)。但作为替代方案,如果您的字符串包含大量反斜杠,您可以使用单引号 heredoc,它不需要转义:
my $path = <<'END';
C:\a\very\long\path
END
chomp $path;
print $path; # C:\a\very\long\path
请注意,heredoc 在末尾添加了一个换行符,您可以使用 chomp
将其删除。
【讨论】:
“你可以使用单引号的heredoc,不需要转义” 谢谢。我一直认为带有单引号终止符的 heredoc 的行为与单引号字符串完全相同,只是没有要转义的“分隔符”,因此必须转义多个反斜杠。我很高兴错了。 我已经编辑了我的问题以说明 Perl 应该区分文字反斜杠和转义反斜杠。【参考方案2】:在单引号字符串中,
反斜杠表示反斜杠,除非后面跟着分隔符或另一个反斜杠,在这种情况下,分隔符或反斜杠被插值。
换句话说,
您必须转义分隔符。 您必须转义\
,后跟\
或分隔符。
您可以转义后面没有\
或分隔符的\
。
所以,
q/\// ⇒ /
q/\\\\a/ ⇒ \\a
q/\\\a/ ⇒ \\a
q/\\a/ ⇒ \a
q/\a/ ⇒ \a
是否需要在单引号字符串中避免反冲?
是的,如果后面跟着另一个反斜杠或分隔符。
如果我想要 2 个反冲,我需要指定 4 个
三个就够了。
这似乎不太方便。
它比双引号字符串更方便,其中反斜杠必须始终被转义。单引号字符串需要尽可能少的转义,而不会失去生成分隔符的能力。
【讨论】:
以上是关于为啥 q/\\a/ 等于 q/\a/?的主要内容,如果未能解决你的问题,请参考以下文章