簡體   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