【问题标题】:How can I interpolate literal \t and \n in Perl strings? [duplicate]如何在 Perl 字符串中插入文字 \t 和 \n? [复制]
【发布时间】:2010-05-16 08:15:52
【问题描述】:

假设我有一个环境变量myvar

myvar=\tapple\n

当下面的命令会打印出这个变量时

perl -e 'print "$ENV{myvar}"'

我实际上将拥有\tapple\n,但是,我希望对这些控制字符进行评估而不是转义。我将如何实现它?

在现实世界中$ENV 居住在替代,但我希望答案能涵盖这一点。

【问题讨论】:

  • 备份一个步骤,为什么你的环境变量里面有这些序列?
  • @brian d foy:因为它们来自文本文件,多行和格式化。

标签: perl


【解决方案1】:

使用eval:

perl -e 'print eval qq{"$ENV{myvar}"}' 

UPD:您还可以使用ee 开关进行替换,这样更安全:

perl -e '(my $s = $ENV{myvar}) =~ s/(\\n|\\t)/"qq{$1}"/gee; print $s'

【讨论】:

  • 直接从环境变量评估代码?听起来像一个安全风险。
  • 这有点冒险,但它似乎是迈克尔需要的答案。
  • 不要这样做。字符串 eval 通常是您需要了解更多 Perl 的标志。 :)
  • @brian d foy:不是真的。如果您想完全按照 Perl 的规则评估某些东西,eval 比手动实现它更有可能是正确的。另一方面,eval 不仅仅是将“\t”翻译成标签——它还可以删除文件:)
  • 好吧,如果您知道自己在做什么,那么 eval 可能是正确的,但这根本不会改变我的说法。大多数时候你仍然会看到一个字符串 eval,它是不正确的,这意味着它做了你想做的,而不做你不想要的(或不知道的)。仅仅因为您知道如何正确使用它并不能否定“大多数”或“经常”。 :)
【解决方案2】:

您可能应该使用String::Escape

use String::Escape qw(unbackslash);

my $var = unbackslash($ENV{'myvar'});

unbackslash 对它找到的任何字符串转义序列进行转义,将它们转换为它们所代表的字符。如果你想明确地只翻译\n\t,你可能不得不自己用substitution 来做,就像this answer一样。

【讨论】:

  • 我唯一担心的是unprintable 翻译的内容可能比您愿意接受的要多。
  • 这是一个很好的观点。让我反思一下……
  • 这个答案听起来与他想做的相反。 “我希望对这些控制字符进行评估而不是逃脱,”他写道。所以看起来“unbackslash”是他想要从那个模块获得的功能。
  • 不准确; unprintable 是评估函数之一。也就是说,我会采纳你的建议和 perldoc 并推荐 unbackslash
【解决方案3】:

包含\ 的字符序列并没有什么特别之处。如果你想用一个字符序列替换另一个字符,在 Perl 中很简单:

my %sequences = (
      '\\t' => "\t",
      '\\n' => "\n",
      'foo' => 'bar',
      );

 my $string = '\\tstring fool string\\tfoo\\n';

 print "Before: [$string]\n";
 $string =~ s/\Q$_/$sequences{$_}/g for ( keys %sequences );
 print "After: [$string]\n";

使用 \ 的唯一技巧是跟踪 Perl 认为它是转义字符的时间。

Before: [\tstring fool string\tfoo\n]
After: [    string barl string  bar
]

但是,作为darch notes,您可能只能使用String::Escape

请注意,当您从环境变量中获取值时,您必须非常小心。我不愿意使用String::Escape,因为它处理的内容可能比您愿意翻译的要多得多。安全的方法是仅扩展您明确希望允许的特定值。请参阅我在Mastering Perl 中的“安全编程技术”一章,其中我谈到了这一点,以及您可能希望在这种情况下使用的污点检查。

【讨论】:

    猜你喜欢
    • 2010-09-21
    • 2019-05-07
    • 2021-03-31
    • 2019-10-24
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多