【问题标题】:parsing out string in csv file type using perl使用 perl 解析 csv 文件类型中的字符串
【发布时间】:2011-10-12 10:52:06
【问题描述】:

我正在使用 perl 的 Tie::File 解析 .csv 文件并匹配特定字符串,它实际上是文件上的第一个字符串/标题。

我遇到的问题可能是我的输入文件类型。导出数据文件的工具可以导出为 .csv 或我尝试和测试过的文本。

不知何故,我仍然没有得到匹配。我的问题可能有两个方面: (1) 我的正则表达式错误和/或 (2) 文件类型。

示例文件头/字符串(如果我cat该文件):

??Global  Mail_Date.Dat

示例文件头/字符串(如果我在编辑器中打开,苹果的 TextEdit.app)

Global  Mail_Date.Dat

这是八进制转储:

0000000 377 376   G  \0   l  \0   o  \0   b  \0   a  \0   l  \0      \0
        feff 0047 006c 006f 0062 0061 006c 0020
0000020      \0   M  \0   a  \0   i  \0   l  \0   _  \0   D  \0   a  \0
        0020 004d 0061 0069 006c 005f 0044 0061
0000040   t  \0   e  \0   .  \0   D  \0   a  \0   t  \0  \r  \0  \n  \0
        0074 0065 002e 0044 0061 0074 000d 000a

显然,执行 os cat 会在字符串上显示前导 ??

代码:

use strict;
use warnings;
use Tie::File;
use File::Copy;

    for (@ARGV) {
        tie my @lines, "Tie::File", $_;             
        #shift @lines if $lines[0] =~ /^Global/;
        if ($lines[0] =~ /^Global/) 
        {
             print "We have a match, remove the line ..";
             #shift @lines if $lines[0] =~ /^Global/;
             untie @lines; 
        }
        else
        { 
             print "No match found. Exit";
        }

}

【问题讨论】:

  • 该??可能是 TextEdit 看到/跳过的 unicode BOM。 cat 只是一个普通的“转储到输出”,不会以任何方式处理文本。
  • 那么,我的正则表达式应该可以工作吧?有没有更好的写法?
  • 不,因为 Perl 也会吸收 BOM。您的正则表达式正在寻找“全局”作为一行中的第一件事 - 它不是 - 在它之前有两个未知字符,因此正则表达式永远不会匹配。
  • 似乎只删除/^Global/ 中的^ 就可以解决问题,除非您希望在其他行出现“全局”一词。也许像/^.{0,2}Global/
  • @Chriszuma - 谢谢。我确实尝试了你的建议,但仍然没有运气。我确实添加了八进制转储(见编辑)。我还想不通。

标签: perl


【解决方案1】:

您的文件似乎是用 utf16 编码的。

试试这样的:

binmode STDIN, ':encoding(UTF-16LE)';
while (<STDIN>) {
  if (m/Global/) {  # see note
    print "Matched Global on line $.\n";
  }
}

如果你得到匹配,那么至少我们知道编码是正确的。

为了补偿 BOM 代码点,您可以在 binmode 调用之后读取单个字符:

binmode STDIN, ':encodeing(UTF-16LE)';
read(STDIN, my $buf, 1);
while (<STDIN>) {
  if (m/^Global/) { ... }
}

【讨论】:

    【解决方案2】:

    我正在查看八进制转储,并注意到每个常规字符之间的空字符。也就是说,它是G-\0-l-\0-o-\0-b-\0-a-\0-l-\0 而不是G-l-o-b-a-l。这意味着您的文件不是 ASCII 文本。这是 UTF8 还是 UTF16?如果是这样,你必须在 Perl 中打开文件时使用encoding 函数:

    open(my $fh, "<:encoding(UTF-16)", $fileName)
        or die qq(Can't open file "$fileName" for reading);
    

    如果这是一个 csv 文件,您应该尝试Text::CSV::Encoded 模块。这将帮助您解析 CSV 文件。

    【讨论】:

      猜你喜欢
      • 2012-02-25
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 2015-03-11
      • 2014-07-19
      • 2017-08-01
      • 1970-01-01
      • 2016-12-16
      相关资源
      最近更新 更多