2014-11-21 32 views
0

我需要匹配同一行中的多個模式。例如,在該文件中:需要匹配同一行中的多個模式 - Perl

Hello, Chester [McAllister;Scientist] lives in Boston [Massachusetts;USA;Fenway Park] # McAllister works in USA 
I'm now working in New-York [NYC;USA] # I work in USA 
... 

首先,我想每一個串入支架知道它可能有超過1種模式,也是我們可以有1至ň串入匹配括號總是用分號分隔。

最後,對於每一行,我需要將這些值與位於#之後的字符串進行比較。例如在第一個句子,我想比較:

[McAllister;Scientist] & [Massachusetts;USA;Fenway Park] TO "McAllister works in USA" 
+1

你的意思是這個'\ [[^; \ n] *(?:; [^; \ n] *)+ \]'http://regex101.com/r/uT5cC0/2' – 2014-11-21 16:23:22

+0

你是什麼試圖做到,讓他們成爲一個數組? – sln 2014-11-21 16:29:33

+0

@AvinashRaj我試過這個'if($ sentence =〜/(\ [[^;] *(?:; [^; * *)+ \])/ g)print $ 1。「\ n」 個; 「但第一行的結果是:'[McAllister;科學家]住在波士頓[馬薩諸塞州;美國;芬威公園]' – 2014-11-21 16:44:34

回答

-1

的整潔的方式可能是使用一個正則表達式,找到所有由方括號分隔嵌入序列,然後使用mapsplit以分離那些序列換成條款。

該程序演示。

請注意,我假設文件中的所有數據已被讀入單個標量變量。你可以改變這一次處理一個單一的線,但只有在括號內的子序列永遠不會跨多行

use strict; 
use warnings; 

my $s = <<END_TEXT; 
Hello, Chester [McAllister;Scientist] lives in Boston [Massachusetts;USA;Fenway Park] # McAllister works in USA 
I'm now working in New-York [NYC;USA] # I work in USA 
END_TEXT 

my @data = map [ split /;/ ], $s =~/\[ ([^\[\]]+) \] /xg; 

use Data::Dump; 
dd \@data; 

輸出拆分

[ 
    ["McAllister", "Scientist"], 
    ["Massachusetts", "USA", "Fenway Park"], 
    ["NYC", "USA"], 
] 
+0

Really powerpul – 2014-11-21 17:02:33

-2

修改 - 鑑於你的更新後,這是一種方式,你可以做到這一點。
它通過代碼塊構造(?{})在主正則表達式中進行拆分。
這樣做有點棘手,但它避免了做一個額外的正則表達式。

主要正則表達式構建@vals陣列和獲取目標串# target..
在每場比賽。其嚴格的線性導向。在每次比賽中,來自@vals的正則表達式構造爲
並且用於匹配目標字符串。

祝你好運!

的Perl

use strict; 
use warnings; 

$/ = undef; 
my $data = <DATA>; 

my @vals; 

while ($data =~/
    ^      # BOL 
    (?{ @vals =() })  # Code block - Initialize @vals 
    (?:      # Text & vals cluster 
      [^\n\[]*     # Text - not newline nor '[' 
      \[      # '[' opening vals bracket 
      (?:      # Vals cluster 
       ([^\n;\]]*)   # (1), Optional value 
       ;?      # Optional ';' 
       (?{ 
        # Code block - Push capture onto @vals 
        push (@vals, $^N) 
        if length $^N; 
       }) 
     )*      # End Vals cluster, do 0 to many times 
      \]      # ']' closing val bracket 
    )*      # End Text & vals cluster, do 0 to many times 
    [^\n#]*     # Text - not newline nor '#' 
    \#      # '#' Target string delimiter 
    (.*)     # (2), Optional Target string 
    $      # EOL 
    /xmg) 
{ 
    my $target = $2; 
    print "----------\n$target\n"; 
    if (@vals) { 
     my $rx = '(' . join('|', map { quotemeta } @vals) . ')'; 
     my $matched = 0; 
     while ($target =~ /$rx/g) { 
      print "$1,"; $matched = 1; 
     } 
     print "\n" if $matched; 
    } 
} 

__DATA__ 

Hello, Chester [McAllister;Scientist] lives in Boston [Massachusetts;USA;Fenway Park] # McAllister works in USA 
I'm now working in New-York [NYC;USA] # I work in USA 
Nothing [here;;; 
Nothing [there;;story;] [;] # End of here story 
# More junk here 

輸出

McAllister works in USA 
McAllister,USA, 
---------- 
I work in USA 
USA, 
---------- 
End of here story 
story, 
---------- 
More junk here 
+0

*任何不包含右括號']的字符串都會匹配'/ [^; \]] *(?:; [^; \]] *)*/x'。沒有必要提及分號';',而只是'/ [^ \]] * /'將具有相同的效果。 – Borodin 2014-11-21 17:01:46

-1

試試這個

這是也給你所期望的。

use strict; 
use warnings; 
open('new',"file.txt"); 
my @z =map{m/\[[\w;\s]+\]/g} <new>; 
print "$_ ,",foreach(@z); 

你的實際需要匹配[]內由;分開的話。

+0

who vote down添加評論 – mkHun 2014-11-21 17:54:45