Perl:正确引用所有特殊字符

时间:2019-01-22 18:41:52

标签: perl quote metacharacters

我有这个示例字符串,其中包含2个反斜杠。请不要问我字符串的来源,它只是一个示例字符串。

my $string = "use Ppppp\\Ppppp;";
print $string;

会同时打印双引号或双引号

use Ppppp\Ppppp;

使用

my $string = "\Quse Ppppp\\Ppppp;\E";
print $string;

将打印

use\ Ppppp\\Ppppp\;

将那些多余的反斜杠添加到输出中。

在perl中是否有一个简单的解决方案来显示字符串“字面意义”,而无需像添加额外的反斜杠那样对字符串进行修改以逃脱?

1 个答案:

答案 0 :(得分:3)

  

我有这个示例字符串,其中包含2个反斜杠。 ...

my $string = "use Ppppp\\Ppppp;";

对不起,但是您误会了-该字符串仅包含一个反斜杠*,因为\\是双引号(和单引号)字符串中的转义序列,产生单个反斜杠。另请参见"Quote and Quote-like Operators" in perlop。如果您的字符串确实包含两个反斜杠,那么您需要编写"use Ppppp\\\\Ppppp;"或使用heredoc,如下所示:

chomp( my $string = <<'ENDSTR' );
use Ppppp\\Ppppp;
ENDSTR

如果您希望将字符串输出为有效的Perl源代码(使用转义),则可以使用以下选项之一:

my $string = "use Ppppp\\Ppppp;";
# option 1
use Data::Dumper;
$Data::Dumper::Useqq=1;
$Data::Dumper::Terse=1;
print Dumper($string);
# option 2
use Data::Dump;
dd $string;
# option 3
use B;
print B::perlstring($string);

其中每个将打印"use Ppppp\\Ppppp;"。 (当然,还有其他模块可用。我个人喜欢Data::DumpData::Dumper是核心模块。)

使用这些模块之一也是验证$string变量确实包含的内容的最佳方法。

如果这仍然不能满足您的需求:您对问题的先前修改是“如何正确转义包括反斜杠的所有特殊字符?” -您必须指定完整列表您认为其中哪些字符特别。您可以这样做,例如:

use 5.014; # for s///r
my $string = "use Ppppp\\Ppppp;";
print $string=~s/(?=[\\])/\\/gr;

将打印$string,反斜杠加倍,而无需修改$string。您还可以在正则表达式字符类中添加更多字符,以在这些字符前面也添加反斜杠。

* 更新:因此,我在这里听起来并不那么古怪:当然,Perl源代码包含两个反斜杠。但是文字源代码和Perl字符串最终包含的内容之间存在差异,就像字符串"Foo\nBar"包含换行符而不是两个文字字符\和{{1}一样}。

为完整起见,如注释中所述:n(又名quotemeta)主要用于转义正则表达式可能特殊的所有特殊字符(所有不匹配的ASCII字符) \Q\E),这就是为什么它也转义了空格和分号。

由于您提到了外部文件:如果您正在从外部文件中读取诸如/[A-Za-z_0-9]/之类的行,则Perl字符串将包含两个反斜杠,而如果您use Ppppp\\Ppppp;,则还将显示两个反斜杠。但是,如果要将字符串表示为Perl源代码,则必须编写print(或使用the question you linked to中的其他方法之一)。