Perl打印到STDOUT是乱码

时间:2014-02-27 17:46:09

标签: string perl printing quotes

我怀疑这是一个“引用”问题,但我无法弄清楚。我有一个perl脚本,它读取包含由用户定义的分隔符分隔的字符串对的文件。称之为“替换文件”。该脚本首先加载对列表,然后读取输入文件。

检查输入文件,替换文件中分隔符的LHS上的每个字符串(调用此srchString)将被RHS上的相应字符串替换(调用此replString)。结果将写入输出文件。替换可以区分大小写或不区分大小写。

为了允许用户指定某些特殊字符,我已经使用了XML中的一些标准字符实体,包括'"srchString& replString是使用这些实体定义的。

现在我想强调替换部分的作用!区分大小写或不区分大小写,我在输出文件中得到了我想要的结果。我遇到困难的地方最后是在报告中。我想写一份报告,显示每个搜索字符串被替换的次数。我在循环中执行此操作,如下所示。你可以看到我尝试了多少变化,但我总是得到相同的乱码结果。 (我尝试进行一些其他更改以确保我运行的是正确的版本代码,因此这不是问题。)

我的替换文件(swSpec.txt):

swap "IT";x:with 'Repl'
abc;x:xyz
Banana;x:Mango

我的输入文件(testInput.txt):

Test 1 : swap "it"
Test 2 : swap "IT"
Test 3 : swap it
Test 4 : abc
Test 5 : ABC
Test 6 : Have a 'Banana' split
Test 7 : Have a 'BANANA' split

为了完整起见,区分大小写的交换提供以下输出(testOutput.txt):

Test 1 : swap "it"
Test 2 : with 'Repl'
Test 3 : swap it
Test 4 : xyz
Test 5 : ABC
Test 6 : Have a 'Mango' split
Test 7 : Have a 'BANANA' split

在我的测试中,我故意使用了一个非常奇怪的分隔符 - ;x:

我得到的报告如下:

' in 1 line(s).swap "IT"' (case sesitive) replaced by 'with 'Repl'
' in 1 line(s).abc' (case sesitive) replaced by 'xyz
testInput.txt:'Banana' (case sesitive) replaced by 'Mango' in 1 line(s).

生成此报告的代码(之前的5次尝试已被注释掉):

for (my $i = 0; $i < $numSwap; $i++) {

  print STDOUT $fil2;
  print STDOUT ":\'";
  print STDOUT $srchList[$i];
  print STDOUT "\' ";
  print STDOUT $caseString;
  print STDOUT " replaced by \'";
  print STDOUT $replList[$i];
  print STDOUT "\' in ";
  print STDOUT $countList[$i];
  print STDOUT " line(s).\n";

  ## 5th change
  #$s1 = $srchList[$i];
  #$s2 = $replList[$i];
  #$d1 = $countList[$i];

  #$rptString = "$fil2: &apos;$s1&apos; $caseString replaced by &apos;".
  #             "$s2&apos; in $d1 line(s).\n";
  #print STDOUT substEntities($rptString);

  ## 4th change
  #$rptString = $fil2.": &apos;".$s1."&apos; ".$caseString." replaced by &apos;".
  #             $s2."&apos; in ".$d1." line(s).\n";
  #print STDOUT substEntities($rptString);

  ## 3rd change
  #$rptString .= ":\'";
  #$rptString .= $srchList[$i];
  #$rptString .= "\' ";
  #$rptString .= $caseString;
  #$rptString .= " replaced by \'";
  #$rptString .= $replList[$i];
  #$rptString .= "\' in ";
  #$rptString .= $countList[$i];
  #$rptString .= " line(s).\n";
  #print STDOUT $rptString;

  ## 2nd change
  #$rptString = $fil2.": '".$srchList[$i]."' ".$caseString." replaced by '".
  #             $replList[$i]."' in ".$countList[$i]." line(s).\n";
  #print STDOUT $rptString;

  ## 1st change
  #$rptString = $fil2.": \'".$srchList[$i]."\' ".$caseString." replaced by \'".
  #             $replList[$i]."\' in ".$countList[$i]." line(s).\n";
  #print STDOUT $rptString;

}

最初我使用带有引号的单个插值字符串打印报告。这给出了与上述所有尝试相同的结果以及我故意介绍的一些细微变化。

作为解释,substEntities()是我在&quot;srchString中用来替换replString等的子例程。

请注意,报告的最后一行是正确的。这就是我想要的。

是否有一种简单的方法可以合理地打印报告?或者我应该在编写报告之前撤消substEntities()行动?任何提示?

1 个答案:

答案 0 :(得分:1)

我正在回答这个问题,所以其他人不需要通过评论。

使用CRLF在带有编辑器(PSPad)的Windows机器上编辑输入数据。测试是在Linux机器上进行的。在操作文本之前,通常使用chomp()删除换行符。但是,在Linux下只删除了LF(\ n),CR(\ r)仍然存在。结果就是你上面看到的混乱输出。

解决方案是编辑文本并指定Unix换行符。包括PSPad在内的大多数编辑都有这种设施。