【问题标题】:Will setting $/="\R" allow chomp() to work correctly with most files in perl?设置 $/="\R" 是否允许 chomp() 正确处理 perl 中的大多数文件?
【发布时间】:2019-01-19 18:23:49
【问题描述】:

是否有人确定设置 $/="\R"; 是否会可靠地让 chomp() 做正确的事情,即删除一行中的任何行尾约定?

具体来说,我在 Windows 和 UNIX 上运行脚本,并且必须处理来自网络的文件,并且具有未知的行尾约定:MS-DOS、UNIX、MacOS

我最近偶然发现了“\R”,但我以前从未见过它。我认为它是新的。嗯,比 Perl 5.006 更新。 (已经有一段时间了。)

“\R”声称也可以使用 Unicode 换行符。我无法正确测试。

谢谢。

-埃里克

我很惊讶地发现 stackoverflow 中实际上有一个“换行符”标签。

【问题讨论】:

    标签: regex perl newline


    【解决方案1】:

    设置 $/='\R' 是否允许 chomp() 正确处理 perl 中的大多数文件?

    $/ 设置为'\R' 会将两个字符序列"\\R" 视为换行符。
    $/ 设置为"\R" 将导致有关Unrecognized escape 的警告。

    \R 不是字符串,但仅在正则表达式的上下文中才有意义。但$/ 的文档明确指出:

    记住:$/ 的值是一个字符串,而不是一个正则表达式。 awk 必须更好。 :-)

    【讨论】:

    • 老鼠。我想在某个地方有一个 perl 模块可以做到这一点。有什么喜欢的吗?
    • @Erik:请记住,如果您使用split ' ', $_,则无论如何都会删除行终止符(以及任何尾随空格)。如果任何类型的尾随空格无关紧要,您也可以使用s/\s+\z// 而不是chomp。最后,您可以安装PerlIO::eol,这将允许您执行open my $fh, '<:raw:eol(LF)', $file,之后all 行结尾将在输入流中显示为简单的LF。显然,必须明确选择输出文件的行终止符。
    • @Erik:您要求替代方案(特别是模块),所以我建议了三种方法。如果您的输出文件完全缺少行终止符,那么您只是用chomp(或其他)删除了它们,而不是将它们放回输出中。当然s/\R\z// 不会让它们神奇地重新出现。
    • @Erik:DOS Ctrl-Z 文件结束标记不应包含在磁盘文件大小中。不再需要它,因为 Windows 现在会跟踪目录条目中文件的大小,与 Linux 一样,所以如果您在输入数据中看到 Ctrl-Z,那么它要么是错误,要么是数据的一部分.很抱歉,如果您觉得我在解决您的问题后还要继续,但很明显,这不仅仅是行尾。所有系统都会在最后一行之后写入没有行终止符的文本文件;如果您使用 chomp 的等效项,则应该没有区别。
    • Re "为什么不用s{\R\z}{} 而不是chomp",为什么不用s{\s+\z}{} 而不是chomp。如果您的格式有大量尾随空格,则说明出现问题。
    【解决方案2】:

    我刚才创建了Acme::InputRecordSeparatorIsRegexp 作为一个玩笑,但它确实为$/ 不能是正则表达式的限制提供了一种解决方法。 0.04版(刚刚上传),你可以说

    use Acme::InputRecordSeparatorIsRegexp ':all';
    
    open my $fh, '<:irs(\R)', 'file-with-ambiguous-line-endings.txt';
    autochomp($fh,1);     # or (tied *$fh)->autochomp(1)
    @lines = <$fh>;
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 2016-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多