使用perl解析csv文件类型中的字符串

发布于 2024-12-09 11:08:37 字数 1343 浏览 1 评论 0原文

我正在使用 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";
        }

}

I am using perl's Tie::File to parse through a .csv file and matching for a specific string, its actually the first string/header on the file.

The problem I am having might be my input file type. The tool that exports the data file can export in .csv or text which I tried and tested both.

Somehow, I am still NOT getting the match. My problem could be two-fold:
(1) my regex is wrong and/or (2) the file type.

Sample file header/string (if I cat the file):

??Global  Mail_Date.Dat

Sample file header/string (if I open up in editor, apple's TextEdit.app)

Global  Mail_Date.Dat

Here's the octal dump:

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

Obviously, doing an os cat shows a leading ?? on the string.

Code:

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";
        }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

在你怀里撒娇 2024-12-16 11:08:37

看起来你的文件是用 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/) { ... }
}

It looks like your file is encoded in utf16.

Try something like this:

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

If you get a match then at least we know the encoding is correct.

To compensate for the BOM code-point, you could read in a single character after the binmode call:

binmode STDIN, ':encodeing(UTF-16LE)';
read(STDIN, my $buf, 1);
while (<STDIN>) {
  if (m/^Global/) { ... }
}
秋意浓 2024-12-16 11:08:37

我正在查看八进制转储并注意到每个常规字符之间的空字符。也就是说,它是 G-\0-l-\0-o-\0-b-\0-a-\0-l-\0 而不是 Global 。这意味着您的文件不是 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 文件。

I'm looking at the octal dump and notice the null character between each of your regular characters. That is, it's G-\0-l-\0-o-\0-b-\0-a-\0-l-\0 and not G-l-o-b-a-l. This means your file is not in ASCII text. Is this in UTF8 or UTF16? If so, you have to use the encoding function when you open the file in Perl:

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

If this is a csv file, you should try the Text::CSV::Encoded module. This will help you parse your CSV file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文