【问题标题】:Trying to parse a text file for a string and print a value试图解析一个字符串的文本文件并打印一个值
【发布时间】:2014-12-09 17:20:45
【问题描述】:

我正在尝试解析目录中包含单词“Phone:”的 40 多个文本文件,并打印字符串后面的电话号码。我是一个超级 perl 新手,所以非常感谢任何帮助。 我必须注释掉 strict 否则它不会运行,

这是我的代码:

#!/usr/bin/perl
#use strict;
use warnings;

my $DIR = "/Ask";
opendir $DIR, '.' or die "opendir .: $!\n";
my @files = grep /\.txt$/i, readdir $DIR;
closedir $DIR;

print "Got ", scalar @files, " files\n";

my %seen = ();
foreach my $file (@files) {
    open my $FILE, '<', $file or die "$file: $!\n";
    while (<$FILE>) {
        #print "test\n";
        if (/^phone\s*(.*)\r?$/i) {
            $seen{$1} = 1;
            foreach my $addr ( sort keys %seen ) {
                print "$addr\n";
            }
        }
    }
    close $FILE;
}

它会看到文件,但似乎从不匹配参数并打印结果。 我还可以轻松地将文件转换为 html 并以这种方式解析它们。

感谢您迄今为止的所有帮助。以下是提出的更多问题以及我正在解析的文件示例:

这是我正在解析的短文件示例 - Agilent Technologies, Inc.总部。免费电话:+1 877-424-4536,电话:4083458886。传真:+1 408-345-8474 地址:5301 Stevens Creek Blvd - 我认为我遇到的问题是电话:并不总是在行的开始。如果我修改我的文件并将其放在那里一切正常,但我认为脚本在一行中间找到它时会遇到问题。想法?

【问题讨论】:

  • 您可能需要在问题中添加 Perl 标签以获得更多相关的查看者。
  • 您的正则表达式中的/^phone 之后是否需要:
  • 是的,将您的正则表达式更改为^phone\s*:\s*(.*)\r?$
  • 你也应该取消评论use strict;
  • 禁用strict 就像在汽车指示灯上贴胶带一样好。在这两种情况下,它看起来都解决了问题。

标签: perl parsing text


【解决方案1】:

几件事

  • 永远不要评论use strict;

  • 不要在 die 消息之后包含换行符,这会告诉 die 隐藏行号和文件消息

  • 您使用 %seen 使您的电话号码独一无二。因此将它们的结果输出到文件处理循环之外。此外,将 %seen 定义为外部循环的词法,否则之前文件中的电话号码仍然存在。

  • 如果您没有得到任何结果,那么您的正则表达式可能不匹配。可能是主播太局限了:^

以下是对脚本的一些清理:

#!/usr/bin/perl
use strict;
use warnings;
use autodie;

my $DIR = "/Ask";

my @files = do {
    opendir my $dh, '.' or die "opendir .: $!";
    grep /\.txt$/i, readdir $dh;
};

print "Got ", scalar @files, " files\n";

foreach my $file (@files) {
    open my $fh, '<', $file or die "$file: $!";

    my %seen;

    while (<$fh>) {
        if (/^phone\s*(.*)$/i) {
            $seen{$1} = 1;
        }
    }

    foreach my $addr ( sort keys %seen ) {
        print "$addr\n";
    }

    close $fh;
}

【讨论】:

  • 感谢到目前为止的所有人。解析html或rtf怎么样?第一个脚本运行良好,第二个脚本给了我以下错误: parse2.pl 第 10 行的 dirhandle 符号错误 - 谢谢,Tony
  • 我在第 10 行有错字。已更正。
  • 谢谢。返回多个字符串如电话、地址、zip 怎么样?
  • 一切皆有可能。但是,您没有分享有关数据性质的信息,因此实际上不可能更详细地为您提供建议。如果你想解析额外的字段,你只需要编写解析程序。
  • 这是我正在解析的短文件的一个示例-Agilent Technologies, Inc.总部。免费电话:+1 877-424-4536,电话:4083458886。传真:+1 408-345-8474 地址:5301 Stevens Creek Blvd - 我认为我遇到的问题是电话:并不总是在行的开始。如果我修改我的文件并将其放在那里一切正常,但我认为脚本在一行中间找到它时会遇到问题。想法?
【解决方案2】:

您将需要 chomp() 每一行以删除每行随附的换行符“\n”:

while (<$FILE>) {
    chomp;
    if (/^phone\s*(.*)\r?$/i) {
        $seen{$1} = 1;
        foreach my $addr ( sort keys %seen ) {
            print "$addr\n";
        }
    }
}

或者,您可以通过添加 's' 修饰符使您的正则表达式多行,这将允许您的“.*”使用换行符:

while (<$FILE>) {
    if (/^phone\s*(.*)\r?$/is) {
        $seen{$1} = 1;
        foreach my $addr ( sort keys %seen ) {
            print "$addr\n";
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-28
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 2012-08-12
    相关资源
    最近更新 更多