代码之家  ›  专栏  ›  技术社区  ›  Yevgeny Simkin

在Perl的文件阅读器中是否有指定行标记分隔符的方法?

  •  1
  • Yevgeny Simkin  · 技术社区  · 15 年前

    我正在通过CGI在Perl中读取一个文本文件,注意到当文件保存在Mac的texttedit中时,行分隔符被识别出来,但是当我上传一个直接从Excel导出的csv文件时,它们不会被识别出来。我猜这是一个\n vs.\r的问题,但它让我觉得我不知道如何指定我希望行终止符令牌是什么,如果我不希望它在默认情况下寻找。

    3 回复  |  直到 15 年前
        1
  •  4
  •   Robert P    15 年前

    对。您将要覆盖的值 $/ . 从 perlvar

    美元/

    输入记录分隔符,默认为换行。这影响了Perl的“行”概念。工作方式与awk的rs变量类似,包括将空行视为终止符(如果设置为空字符串)。(空行不能包含任何空格或制表符。)可以将其设置为多字符字符串以匹配多字符终止符,也可以设置为取消定义以读取文件结尾。如果文件包含连续的空行,则将其设置为“\n\n”表示与设置为“”稍有不同。设置为“”将把两个或多个连续空行视为单个空行。设置为“\n\n”将盲目假定下一个输入字符属于下一段,即使它是换行符。(助记法:在引用诗歌时划定行边界。)

    local $/;           # enable "slurp" mode
    local $_ = <FH>;    # whole file now here
    s/\n[ \t]+/ /g;
    

    记住:$的值是一个字符串,而不是regex。awk必须做得更好。-)

    将$/设置为对整数、包含整数的标量或可转换为整数的标量的引用将尝试读取记录而不是行,最大记录大小为引用的整数。所以这是:

    local $/ = \32768; # or \"32768", or \$var_containing_32768
    open my $fh, "<", $myfile or die $!;
    local $_ = <$fh>;
    

    将从文件中读取不超过32768字节的记录。如果你没有从一个面向记录的文件中读取(或者你的操作系统没有面向记录的文件),那么每次读取都可能得到一整块数据。如果一条记录大于您设置的记录大小,您将以片段形式重新获得该记录。尝试将记录大小设置为零或更小将导致读取整个文件(其余部分)。

    在vms上,记录读取是使用与sysread等效的方法完成的,因此最好不要在同一个文件上混合记录和非记录读取。(这不太可能是一个问题,因为您希望在记录模式下读取的任何文件在行模式下都可能不可用。)非VMS系统执行正常的I/O,因此可以安全地混合记录和非记录读取文件。

    另请参见Perlport中的“newlines”。另见美元。

        2
  •  2
  •   Jonathan Leffler    15 年前

    变量有多个名称:

    • $/
    • $RS
    • $INPUT_RECORD_SEPARATOR

    对于较长的名称,您需要:

    use English;
    

    记住要小心地本地化:

    {
    local($/) = "\r\n";
    ...code to read...
    }
    
        3
  •  1
  •   daotoad    15 年前

    如果正在使用CRLF行终止符读取文件,可以使用CRLF规则打开它,或者将句柄的binmode设置为执行自动转换。

    open my $fh, '<:crlf', 'the_csv_file.csv' or die "Oh noes $!";
    

    这将透明地转换 \r\n 序列转换为 \n 序列。

    您还可以通过执行以下操作将此转换应用于现有句柄:

    binmode( $fh, ':crlf' );
    

    :crlf 模式在Win32Perl环境中通常是默认的,在实践中工作得很好。