繁体   English   中英

Perl正则表达式帮助(解析列)

[英]Perl regular expression help (parse out column)

我被困在这里。 不知道为什么我的reg ex无法使用。 我有一个由管道分隔的带有一系列列的文本文件。 我需要提取第三列。

文件:

A|B|C|D|E|F|G|H|I
2011-03-03 00:00:00.0|1|60510271|254735|27751|BBB|1|-0.1619023623|-0.009865904
2011-03-03 00:00:00.0|1|60510270|254735|27751|B|3|-0.0064786612|-0.0063739185
2011-03-03 00:00:00.0|1|60510269|254735|27751|B|3|-0.0084998226|-0.009244384

正则表达式:

$> head foo | perl -pi -e 's/^(.*)\|(.*)\|(.*)\|(.*)$/$3/g'

输出量

-0.1619023623
-0.0064786612
-0.0084998226

显然,输出的列不正确。

有什么想法吗?

通常,更容易/更简单(KISS)不要将正则表达式用于具有结构化分隔符的文件格式。 只需在“ |”上分割字符串 定界符并获得第三个字段。

awk -F"|" '{print $3}' file

使用Ruby(1.9+)

ruby -F"\|" -ane 'puts $F[2]' file

使用Perl,其类似于上面的Ruby单一代码。

perl -F"\|" -ane 'print $F[2]."\n"' file

.*默认情况下,比赛将尽可能多的,因为它可以,所以你的RE被挑选出最后三列(和之前的一切),而不是三个(一切后)。 您可以(至少)通过两种方式避免这种情况:(1)代替.* ,寻找[^|]* ,或(2)使您的重复运算符不贪心: .*? 代替.*

(或者,您可以显式地拆分字符串,而不是将整个内容与单个RE进行匹配。您可能想尝试两种方法,如果有关系的话,看看哪种方法效果更好。拆分可能会给出更长但更清晰的代码。)

如何使用真正的解析器而不是一起破解正则表达式? Text::CSV应该可以完成这项工作。

my $csv = Text::CSV->new({sep_char => "|"});

您需要使模式变得贪婪-因此:

's/^(.*?)\\|(.*?)\\|(.*?)\\|(.*)$/$3/g'

首先想到的是Text :: CSV(由Matt B提到),但是如果数据看起来像示例,我会说split是正确的选择。

未经测试:

$> head foo | perl -le 'while (<>) { print (split m{|})[2]; }'

如果您真的想使用正则表达式,则可以使用以下命令:

s{^ [^\|]* \| [^\|]* \| ([^\|]*) \| .*$}{$1}gx;
(?<=\|)\d{8}

也许这会起作用(?<=\\|)积极寻找| 字符后跟8位数字

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM