2012-07-12 214 views
1

非常感謝您花時間閱讀此內容。我對Perl仍然很陌生,所以任何幫助表示讚賞!提取正則表達式匹配中的第N個子組

我想用一個正則表達式從一大組大文檔中提取一段文本。

我有一個正則表達式,我用它來識別我想要開始提取的較大文檔中的哪個位置。這個正則表達式的條件是經常有多個匹配正則表達式的實例。我能夠識別哪些匹配是我想要提取的文本主體的開始。 (在下面的示例中,這將是$ finds [2]。

我想要做的是再次運行相同的正則表達式,添加一個。*?$ END以提取文本,其中$ END標識。結束,但我需要的是一種方式來告訴正則表達式開始在$ STAR的第N次出現提取

考慮這個:

my $sentence = 'A1Z blah blah A2Z blah blah A3Z blah A4Z END A5Z'; 
my @finds = $sentence =~ m/(A\dZ)/mg; 

#################### 
## Code that determine the element of @finds that 
## contains the match to the extraction I want. 
## For this question assume it is the third match (A3Z), 
## Element index number 2. 
#################### 

$START = 2; 

這裏是我的嘗試:

my @finds2 = ($sentence =~ m/((A\dZ){$START}.*?(END))/mg); 

my @finds2 = ($sentence =~ m/((A\dZ)[$START].*?(END))/mg); 

如果向PERL指示的{$ START}或[$ START]等到它具有「$ START」匹配,纔開始提取並繼續匹配,那麼我希望它。

我知道我的嘗試是不正確的。希望他們幫助指出我正在嘗試做什麼。

回答

3

這是做你喜歡的事嗎?

my $pos = 3 
my $END = "END"; 
my $a = "A1Z blah blah A2Z blah blah A3Z blah A4Z END A5Z"; 
$a =~/(?:.*?A\dZ){$pos} (.*?) $END /x; 
print $1, "\n" if defined $1;' 
# prints " blah A4Z " 

此代碼將尋找A \ DZ模式(在$pos指定數量)的n次發生和直到遇到在$ END模式啓動後保存到$1。如果你確實需要性能,我會建議看看\G斷言,這將匹配你以前的比賽離開的地方。這可以與內置的soubroutine pos混合使用。防止「回溯」也可以提高性能,但這是一個我不太瞭解的高級主題。

推薦讀物:「perlop - Regexp Quote-Like Operators」,「perlre - Assertions」和「perldoc -f pos」。

(另一種可能性可能會區分你的投入較小的字符串,但在許多情況下,最簡單的Perl的解決方案也是最好的。)

+0

+1很好的回答。 – sln 2012-07-13 01:12:27