【问题标题】:Preserving backslashes in Perl strings在 Perl 字符串中保留反斜杠
【发布时间】:2013-04-23 11:56:50
【问题描述】:

在 Perl 中有没有一种方法可以保存和打印字符串变量中的所有反斜杠? 例如:

$str = 'a\\b';

输出是

a\b

但我需要

a\\b

问题是无法以任何方式处理字符串以转义反斜杠,因为 我必须从数据库中读取复杂的正则表达式,并且不知道它们出现在哪个组合和数字中,并且必须完全按照它们在网页上的形式打印它们。

我尝试使用模板工具包以及 html 和 html_entity 过滤器。到目前为止,唯一可行的方法是使用单引号此处的文档:

print <<'XYZ';
a\\b
XYZ

但是我不能插入变量,这使得这个解决方案毫无用处。

我尝试将字符串写入网页、文件和 shell,但没有运气,总是有一个反斜杠消失。也许我完全走错了路,但是打印复杂正则表达式的正确方法是什么,包括所有组合和数字中的反斜杠而不做任何更改?

换句话说: 我有一个包含数百个正则表达式作为字符串数据的数据库。我想用 perl 阅读它们并将它们打印在网页上,就像它们在数据库中一样。 许多管理员一直在对这些正则表达式进行更改,所以我事先不知道如何以及如何逃避。 一个典型的例子如下所示: 'C:\\test\\file \S+' 但它可能会在第二天更改为 '\S+ C:\\test\\file' 也许一个正确的结论是,无论它出现在哪个组合和哪个数字中,都将每个反斜杠精确地转义一次?这意味着它可以将它们加倍。那么问题就没有我担心的那么大了。我在 bash 上对其进行了测试,它可以连续使用两个甚至三个反斜杠(4 个反斜杠打印 2 个反斜杠,6 个反斜杠打印 3 个反斜杠)。

【问题讨论】:

  • 请举例说明你想做什么。一旦反斜杠在变量中,它们将保持不变,并且如果它们被插入到字符串中,它们将正确显示。将一对反斜杠放入字符串 literal 的唯一方法是将它们加倍,但这应该不是问题。有几个软件层将反斜杠视为转义字符,因此您的问题可能不在 Perl 中。

标签: perl backslash preserve


【解决方案1】:

反斜杠仅在 Perl 源代码中出现时才对 Perl 有意义,例如:将文字字符串分配给变量:

my $str = 'a\\b';

但是,如果您从文件(或数据库或套接字等)读取数据,您读取的数据中的任何反斜杠都将被保留,您无需采取任何特殊步骤。

【讨论】:

  • 是的,完全正确。有时,显而易见的事情需要时间来理解。现在一切都清楚了。谢谢。
【解决方案2】:
my $str = 'a\\b';
print $str;

这会打印出a\\b。

使用 我的 $str = 'a\\\\b'; 而是

【讨论】:

  • 不,它打印a\b
  • Stackoverflow 跳过了额外的反斜杠。
【解决方案3】:

这是一个 PITA,但你只需要将反斜杠加倍,例如

 a\\\\b

否则,您可以将反斜杠存储在另一个变量中,然后对其进行插值。

【讨论】:

    【解决方案4】:

    获得两个斜线的最小值是(不幸的是)三个斜线:

    use 5.016;
    my $a = 'a\\\b';
    say $a;
    

    【讨论】:

      【解决方案5】:

      我试图解决的问题不存在。我将直接在代码中初始化字符串与使用 html 表单混淆了。在保留所有反斜杠的代码中使用字符串只能使用此处的文档或读取包含该字符串的文本文件。但是,如果我只是在网页上使用 html 表单插入字符串并使用 CGI 模块中的 escapeHTML() ,它会处理所有事情,您可以插入最连线的特殊字符组合。它们都完全按照插入的方式显示和保存。所以我应该直接从 html 和数据库操作开始,而不是先检查事情 通过直接在代码中使用字符串。无论如何,感谢您的帮助。

      【讨论】:

        【解决方案6】:

        您可以使用以下正则表达式来正确地形成您的字符串:

        my $str = 'a\\b';
        $str =~ s/\\/\\\\/g;
        print "$str\n";
        

        这打印a\\b。

        编辑:

        您可以使用非插值 here-document 代替:

        my $str = <<'EOF';
        a\\b
        EOF
        print "$str\n";
        

        这仍然打印a\\b。

        【讨论】:

        • 谢谢,但只有在字符串中将反斜杠加倍时才有效。如果你有一个额外的单反斜杠,它会在输出中加倍。
        • 您的s/\\/\\\\/g 解决方案不适用于@Norbert 指出的任意正则表达式字符串。然而,您的第二个建议正是我所需要的。
        【解决方案7】:

        格兰特的回答提供了我需要的提示。其他一些答案与 Perl 在我的系统上的操作不匹配,所以......

        #!/usr/bin/perl
        use warnings;
        use strict;
        
        my $var = 'content';
        
        print "\'\"\N{U+0050}\\\\\\$var\n";
        
        print <<END;
        \'\"\N{U+0050}\\\\\\$var\n
        END
        
        print '\'\"\N{U+0050}\\\\\\$var\n'.$/;
        
        my $str = '\'\"\N{U+0050}\\\\\\$var\n';
        print $str.$/;
        
        print @ARGV;
        print $/;
        

        从 bash 调用...使用 bash 转义引号的方法,将 \' 更改为 '\''。

        jamie@debian:~$ ./ft.pl '\'\''\"\N{U+0050}\\\\\\$var\n'
        '"P\\\content
        '"P\\\content
        
        '\"\N{U+0050}\\\$var\n
        '\"\N{U+0050}\\\$var\n
        \'\"\N{U+0050}\\\\\\$var\n
        

        最后一行,中间有六个反斜杠,是我所期望的。现实不同。

        所以:

        • “in here \”被插值
        • 在 HEREDOC \ 中被插值
        • 'in single quotes only \' 被插值并且仅用于\和'(还有更多吗?)
        • my $str = '同样有限\插值';
        • perl.pl 'escape using bash rules' with @ARGV is not interpolated

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多