我有一個4GB的文本文件,其長度高度可變,這只是一個示例文件,生產文件將會大得多。我需要讀取該文件並應用多行正則表達式。Perl讀取一個大文件用於多行正則表達式
什麼是閱讀這樣一個大型文件的多行正則表達式的最佳方式是什麼?
如果我逐行閱讀它,我不認爲我的多行正則表達式可以正常工作。當我在3參數形式中使用read函數時,我的正則表達式結果會隨着我在read語句中指定的長度的大小而改變。我相信文件的大小使它太大而無法讀入數組或內存。
這是我的代碼
package main;
use strict;
use warnings;
our $VERSION = 1.01;
my $buffer;
my $INFILE;
my $OUTFILE;
open $INFILE, '<', ... or die "Bad Input File: $!";
open $OUTFILE, '>',... or die "Bad Output File: $!";
while (read $INFILE, $buffer, 512 ) {
if ($buffer =~ /(?m)(^[^\r\n]*\R+){1}^(B|BREAK|C|CLOSE|D|DO(?! NOT)|E|ELSE|F|FOR|G|GOTO|H|HALT|HANG|I|IF|J|JOB|K|KILL|L|LOCK|M|MERGE|N|O|OPEN|Q|QUIT|R|READ|S|SET|TC|TRE|TRO|TS|U|USE|V|VIEW|W|WRITE|X|XECUTE)(|:).*[^\r\n]/) {
print $OUTFILE $&;
print $OUTFILE "\n";
}
}
close($INFILE);
close($OUTFILE);
1;
下面是一些示例數據:
^%Z("EUD")
S %L=%LO,%N="E1"
^%Z("RT")
This is data that I don't want the regex to find
^%Z("EXY")
X ^%Z("EW2"),^%Z("ELONG"):$L(%L)>245 S %N="E1" Q:$L(%L)>255 X ^%ZOSF("EON") S DX=0,DY=%EY,X=%RM+1 X ^%ZOSF("RM"),XY K %EX,%EY,%E1,%E2,DX,DY,%N Q
^%Z("F12")
S %A=$P(^DIC(9.8,0),"^",3)+1,%C=$P(^(0),"^",4)+1 X "F %=0:0 Q:'$D(^DIC(9.8,%A,0)) S %A=%A+1" S $P(^DIC(9.8,0),"^",3,4)=%A_"^"_%C,^DIC(9.8,%A,0)=%X_"^R",^DIC(9.8,"B",%X,%A)=""
^%Z("F2")
S %=$H>21549+$H-.1,%Y=%\365.25+141,%=%#365.25\1,%D=%+306#(%Y#4=0+365)#153#61#31+1,%M=%-%D\29+1,%DT=%Y_"00"+%M_"00"+%D,%D=%M_"/"_%D_"/"_$E(%Y,2,3)
上述線是成對的,語法(線1和2一起去,3和4等)。我需要找到特定的對,這是所有的對除上述數據:
^%Z("RT")
This is data that I don't want the regex to find
看起來你正在嘗試使用多行正則表達式來解析DSL(doman特定語言)。這幾乎總是一個可怕的想法,因爲格式可能差異很大。這似乎是一個[XY問題](http://xyproblem.info),你已經走下了思考的正確的工具,正確的工具,當它幾乎肯定不是。你應該做的是編輯你的問題,包括一個有代表性的輸入樣本,並描述你的最終目標。 –
因爲它看起來足夠複雜,以便以後擴展和更精確的解析,我會建議使用[Pegex](https://metacpan.org/pod/distribution/Pegex/lib/Pegex.pod)來構建解析器。開始有點陡峭(需要學習Pegex並編寫語法規則),但稍後它可能會付錢... – jm666
提醒,請參閱[當某人回答我的問題時該怎麼辦?](http://堆棧溢出。com/help/someone-answers) – zdim