[英]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.