2012-07-23 102 views
4

我已經繼承了一個perl腳本,用於從某些文件中提取數據。整個腳本工作正常,但最近一些工程師已經爲一個通常需要一個號碼的地點輸入了多個號碼,所以輸出並沒有顯示出預期的全部內容。Perl正則表達式

樣品輸入:

CRXXXX: "Then some text"

CRs XXXX, XXXX, XX, XXX

CRXXX "Some Text"

目前這個表達式語句我翻出CR後的數字,但如果給定的樣本輸入的那麼第二行就打印"s XXXX, XXXX, XX, XXX"而不是想要的"XXXX XXXX XX XXX"

我對perl非常陌生,並且正在努力弄清楚如何改變這個正則表達式來處理所有的輸入。

$temp_comment =~ s/\s[cC][rR][-\s:;]*([\d])/\n$1/mg; 

提前感謝!

布洛克

+0

這是非常不清楚。你不能給我們一些*真實的*數據和你想要的相應的輸出嗎? 「X」字符應該是數字嗎? – Borodin 2012-07-23 19:11:05

+0

Brock,其他兩行輸入的預期輸出是多少?您的正則表達式是否應該與CRXXX部分或後面的「某些文本」匹配? – 2012-07-23 19:11:58

+0

你想要什麼輸出? – ikegami 2012-07-23 19:16:36

回答

2

對於這樣的樣本數據:

my $temp_comment = 
'CR1234: "Then some text" 
CRs 2345, 3456, 45, 567 
CR678 "Some Text"'; 

嘗試:

$temp_comment =~ s/(,)|[^\d\n]+/$1?' ':''/semg; 

,或者,如果你想貼近字符串模板:

$temp_comment =~ s/^    # multi-line mode, line start 
        \s*    # leading blanks? 
        CR    # CR tag 
        \D*    # non-number stuff 
        (     # start capture group 
         (?:\d+ [,\s]*)+ # find (number, comma, space) groups 
        )     # end capture group 
        \D*    # skip remaining non-number stuff 
        $     # multi-line mode, line end 
        /$1/mxg;   # set multi-line mode + regex comments "x" 

但你必須刪除數字組中的逗號後續步驟。

$temp_comment =~ tr/,//d;    # remove commas in the whole string 

$temp_comment =~ s/(?<=\d),(?=\s\d)//g; # remove commas between numbers '11, 22' 

對於 「足下」,你必須使用/e修改:

$temp_comment =~ s{^    # line start 
        \s*    # leading blanks? 
        CR    # CR tag 
        \D*    # non-number stuff 
        ((?:\d+ [,\s]*)+) # single or group of numbers 
        \D*    # non number stuff 
        $     # line end 
        } 
        {do{(local$_=$1)=~y/,//d;$_}}mxeg; 

這意志,在上述數據,導致:

1234 
2345 3456 45 567 
678 

但的確,請使用,如果可能的話,更簡單的兩步法。後一個正則表達式可能會成爲繼任者的維護噩夢。

+0

我需要它來分隔在輸入中分組的每組數字。如CR1234,111,333,3453,55555這將理想變成 「1234 111 333 3453 55555」,甚至這1234 \ n 111 \ n 333 \ n 3453 \ n 55555 – user1546666 2012-07-23 19:38:50

+0

** **究竟如何看你的輸入數據?你有單行嗎?或者在行之間加上換行符'\ n'的$變量(就像我發佈的那樣)?輸入dat的輸出如何?那麼換行符呢? – 2012-07-23 19:45:23

+0

數據線之間有一條新線。像上面一樣。而第二個你打字的作品或最好的,我想我只需要把逗號變成換行符 – user1546666 2012-07-23 19:52:09

1

你可能會更好做這兩個步驟:

1)創建你的正則表達式

s/\s[cC][rR][-\s:;]*([\d\ ]+)/\n$1/mg(注意捕捉所有號碼的新途徑,你只捕獲上面的第一個數字)

2)然後用find/replace去掉字符串中的逗號。

1
my ($v) = /CR[s ]*((?:\d+[\s,]*)*)/ig; 
$v =~ s/,//g; 
print $v,"\n"; 
+0

對於一個Perl的新手(中OP),您應該添加表達式('__')的上下文,並指出原始**替換**和您的**匹配**之間的差異。 – 2012-07-23 20:09:03

1

或許下面會爲你工作:

use Modern::Perl; 

say join ' ', (/(\d+)/g) for <DATA>; 

__DATA__ 
CR1234: "Then some text" 
CRs 1111, 2222, 33, 444 
CR567 "Some Text" 

輸出:

1234 
1111 2222 33 444 
567 

希望這有助於!