Perl换行符未在单引号字符串(或从文件读取的行)中强制执行

时间:2018-09-20 16:06:29

标签: perl

我有一个Perl脚本来逐行读取文件,其中某些行中包含换行符(\ n),但未强制执行。

这是我尝试但不为我工作的示例

    my $var1 = 'Hello \n world';
    my $var2 = "$var1";
    my $var3 = '$var1';

    print "    $var2 \n" ;
    print $var3;

输出是

       Hello \n world
       $var1

但是我想要下面的

        Hello
        world

当我从文件中读取一行时,该行中包含换行符,并且需要强制使用换行符。

3 个答案:

答案 0 :(得分:2)

单引号''不能插入变量或控制字符。

这只是Perl的工作方式。

如果您print '\n'将打印文字反斜杠\和文字n n。如果将其分配给变量,则还将分配文字反斜杠和文字n。

将变量插值到"$foo"之类的另一个字符串中只会插值$foo,但仍将包含文字反斜杠和文字n。

如果还要进行插值,则必须使用字符串eval

my $foo = 'Hello\nWorld';
print eval "qq{$foo}";

双引号""用于将$foo内插到值Hello\nWorld,因此eval将显示文字文本,而qq{}将双引号引号用于将字符串包装到插值双引号中,以便eval将其视作插值。

但是请不要那样做。在大多数情况下,您不想使用字符串eval


由于您正在谈论从文件读取,因此有所不同。如果您从文件中读取字符串,并且该字符串包含文字\和文字n,则该字符串不是换行符\n转义序列只是用于创建换行符0x0A in ASCII的视觉表示。因此,您的文件中没有任何特殊内容。只是两个字符。

在处理文件时,可以用\替换文字n\n

while (my $line = <$fh>) {
    chomp $line;
    $line =~ s/\\n/\n/g; # \\ creates literal backslash, second half is interpolated
}

答案 1 :(得分:2)

您似乎认为print会将\n转换为换行符,但事实并非如此。如您所知,如果您从文件中读取Hello \n world␊并将其传递给print,它将打印Hello \n world␊

产生转换后的字符串的是双引号字符串文字本身。例如,

  • 字符串文字'Hello \n world'产生14个字符的字符串Hello \n world
  • 字符串文字"Hello \n world"产生13个字符的字符串Hello ␊ world

如果要对输入执行某种转换,则需要告诉Perl进行转换。

my $s = 'Hello \n world'."\n";
$s =~ s/\\n/\n/g;
print($s);

答案 2 :(得分:0)

如果要在示例中用换行符和空格替换文字序列\n

use warnings;
use strict;

my $var1 = 'Hello \n world';
my $var2 = "$var1";
my $var3 = '$var1';

my $s = "    $var1 \n";
$s =~ s/\\n/\n   /;
print $s

输出:

    Hello
    world

但是,如果空白不是示例输出的意外产物,请在文件上使用s/\\n/\n/。这种情况很好地说明了Perl字符串中的string interpolation\n\\n或转义的换行符。