【问题标题】:Trying to understand Perl split() output试图理解 Perl split() 输出
【发布时间】:2011-05-24 15:40:51
【问题描述】:

我尝试使用 Perl 的 split 函数将几行文本转换为数组。问题是我在输出中得到了一些不寻常的额外字符,特别是以下字符串“\cM”(不带引号)。该字符串出现在原文有换行符的地方;但是,(我相信)这些换行符已在我尝试拆分的文本中删除。有人知道这种现象是怎么回事吗?我在下面发布了一个示例。谢谢。

这是我尝试拆分的原始纯文本。我正在从文件中加载它,以防万一:

10b2obo12b2o2b$6b3obob3o8bob3o2b$2bobo10bo3b2obo4bo2b$2o4b2o5bo3b4obo
3b2o2b$2bob2o2bo4b3obo5b4obob$8bo4bo13b3o$2bob2o2bo4b3obo5b4obob$2o4b
2o5bo3b4obo3b2o2b$2bobo10bo3b2obo4bo2b$6b3obob3o8bob3o2b$10b2obo12b2o!

这是我应该进行拆分的 Perl 代码:

while(<$FH>) {
    chomp;
    $string .= $_;
    last if m/!$/;
}

@rows = split(qr/\$/, $string);
print;          # a dummy line to provide a breakpoint for the debugger

这是调试器在到达“打印”行时输出的内容。我试图处理的问题出现在第 3、7 和 10 行:

DB<10> p $string
2o5bo3b4obo3b2o2b$2bobo10bo3b2obo4bo2b$6b3obob3o8bob3o2b$10b2obo12b2o!
DB<11> x @rows
0  '10b2obo12b2o2b'
1  '6b3obob3o8bob3o2b'
2  '2bobo10bo3b2obo4bo2b'
3  "2o4b2o5bo3b4obo\cM3b2o2b"
4  '2bob2o2bo4b3obo5b4obob'
5  '8bo4bo13b3o'
6  '2bob2o2bo4b3obo5b4obob'
7  "2o4b\cM2o5bo3b4obo3b2o2b"
8  '2bobo10bo3b2obo4bo2b'
9  '6b3obob3o8bob3o2b'
10  "10b2obo12b2o!\cM"

【问题讨论】:

    标签: perl


    【解决方案1】:

    您知道,更改文件输入分隔符会使这段代码更简单。

    $/ = '$';
    
    my @rows = <$FH>;
    chomp @rows;
    
    print "@rows";
    

    【讨论】:

    • 实际上,如果$/ 设置为$chomp 将截断任何尾随$,而不是换行符。 ;) 为独创性 +1。
    • 我确切地知道 chomp 的行为,谢谢 :) OP 说他已经解决了 CR/LF 问题。我只是在提供一种更有效的方法来解决他原来的问题。
    【解决方案2】:

    调试器可能使用\cM 来表示Ctrl-M,也称为回车(有时是\r^M)。 Windows 中的文本文件使用 CR-LF(回车、换行)对来表示行尾。如果您在 Unix 系统上读取这样的文件,您的 chomp 将删除 Unix EOL(单行馈送),但保留 CR 原样,最终您的文件中会出现杂散的 CR。

    对于像你这样的文件,你可以去掉所有尾随空格而不是使用chomp

    while(defined(my $line = <$FH>)) {
        $line    =~ s/\s+$//;
        $string .= $line;
        last if($line =~ /!$/);
    }
    

    【讨论】:

    • 对于更通用的解决方案,是否可以检查文件类型,并为chomp 分配正确的$/ 值?
    • @TLP:我认为您能做的最好的事情就是阅读一行,看看它正在使用什么 EOL。或者只是去掉所有 CR 或 LF 的尾随序列,并假装问题不存在 :)
    【解决方案3】:

    你没有说你在哪个操作系统上。 查看 binmode 以及它对 \cM 的看法,它们的位置与输入文件的行尾一致:

    http://perldoc.perl.org/functions/binmode.html

    【讨论】:

    • 我真的很感激这一点,因为我不知道在 perldoc 中的何处寻找答案。我使用的是 Mac……虽然我认为“chomp”的全部意义在于摆脱行终止符。
    • 我通过引入 pragma use open IN =&gt; ":crlf"; 解决了这个问题。不过,不确定这是否会破坏其他平台上的应用程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多