【问题标题】:Perl - Getting value from comma separated linePerl - 从逗号分隔的行中获取值
【发布时间】:2014-06-21 23:18:27
【问题描述】:

我有一个要重写的 perl 文件解析器。 这是一个动态解析器​​,我需要从逗号分隔的行中提取一个值。

我想从中获取一个值的行看起来像这样:

ENTRYNAME-8,44544,99955,52,156,15:16:16,15:19:16

这是每个已解析文件中唯一以ENTRYNAME- 开头的行。- 之后的所有内容都会因每个正在解析的文件而更改

我想要第二个逗号后的值。 (上例中的99955

我尝试了以下方法,但没有任何运气:

if (/ ENTRYNAME-\((.*)\,(.*)\,(.*)\)/ ) 
{
    $entry_nr = $3;
    print "entry number = $entry_nr";
    next;
}

【问题讨论】:

  • 最好使用Text::CSV,或者至少在分隔符上分割线split /,/
  • 这些 csv 行是否会被引用并在字符串中嵌入 ','?

标签: perl


【解决方案1】:

问题是你的第一个捕获字符串.* 是贪婪的,所以它会消耗你所有的字符串。然后它将回溯以找到两个逗号,并从末尾开始匹配。

还有:

  • 出于某种奇怪的原因,您正在匹配文字括号 \(。由于您没有任何此类,因此它们永远不会匹配。
  • 您不需要转义逗号\,
  • 您的正则表达式 / ENTRY... 中不能有随机空格,除非您的目标字符串中有一个空格
  • 您不需要捕获不打算使用的字符串

一个简单的解决方法是使用更严格的捕获组(包括以上几点):

if (/ENTRYNAME-\d+,\d+,(\d+)/ ) 

这将捕获到$1

正如 mpapec 在评论中指出的那样,您可能希望使用 Text::CSV 来解析 CSV 数据。会安全很多。如果你的数据足够简单,这个解决方案就可以了。

【讨论】:

  • 谢谢!这终于让这一切走到了一起。我会使用 Text::CSV,但输入数据无论如何都不简单。
  • @user2837756 如果你有正确的 csv 数据,你应该只使用Text::CSV。对于变化有限的有限数据集,正则表达式是一种可行的小规模解决方案。但是您可能应该添加一些安全防护和错误报告,以防遇到意外变化。
【解决方案2】:

直接拆分成数组并寻址:

my @a = split /,/, $_;
print $a[2];

这里发生的是 $_ 中的任何内容(通常来自for (@allmylines) {-loop)将在每次出现, 时被拆分,将它们全部放入一个数组(@a)并删除@987654325 @。然后您可以寻址数组中的字段,从第一个字段的 0 开始。因此,如果您想解决第三个字段,请使用$a[2] 检索第三个项目。

【讨论】:

  • @Brett_Schneider 如果每一行都包含嵌入逗号的引用字符串怎么办?
  • @octopusgrabbus 它没有在问题中说明任何内容,因此我认为花时间考虑它没有意义。
  • @Victor 我已经考虑过了,因此将我的答案扩展到这一点。
【解决方案3】:

尽可能将解析与处理和验证数据分开。

在这种情况下,如果您有逗号分隔值,请继续分隔这些值。然后担心过滤您的数据。是否使用Text::CSV 进行解析是一个单独的问题,尽管这可能是个好主意。

use strict;
use warnings;

while (<DATA>) {
    chomp;
    my @cols = split ',';

    if ($cols[0] =~ /^ENTRYNAME/) {
        print $cols[2], "\n";
    }
}

__DATA__
ENTRYNAME-8,44544,99955,52,156,15:16:16,15:19:16

输出:

99955

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2020-08-19
    • 2016-11-12
    相关资源
    最近更新 更多