2016-05-12 24 views
1

我正在嘗試編寫一個正則表達式,該正則表達式將從日誌文件返回多行匹配。使用下面的示例 - 我想匹配一個完整的「事務」,該事務的開始和結束都與日誌中的所有其他事務(開始和結束)相同的文本。但是 - 在這些行之間有一個自定義標識符 - 在這種情況下是一個電子郵件地址,可以區分一個事務和另一個事務。需要正則表達式來匹配多行,直到在共同分隔符之間找到匹配

Start of a transaction. 
random line 1. 
random line 2. 
[email protected] 
End of a transaction. 
Start of a transaction. 
random line 1. 
random line 2. 
[email protected] 
random line 3. 
End of a transaction. 

這裏是我開始有:

^Start(.*?)\n(((.*?)(email1\@gmail\.com)(.*?)|(.*?))\n){1,}End (.*?)\n 

本質 - 我想說:以「開始」開始 - 並匹配所有行,直到「終結」行,但只能返回如果其中一行包含特定電子郵件地址,則爲匹配項。

現在 - 我的正則表達式將整個日誌文件視爲單個匹配,因爲大概第1行包含「開始」,第X行包含「結束」以及中間數百行中的某處 - 它們是匹配電子郵件。另外 - 應用程序是Powershell,並將使用選擇字符串模式,如果這很重要。

回答

2

使用negative lookahead assertion,以確保您的正則表達式從未跨越邊界「交易結束」匹配:

preg_match_all(
    '/^        # Start of line 
    Start\ of\ a\ transaction\.  # Match starting tag. 
    (?:        # Start capturing group. 
    (?!End\ of\ a\ transaction)  # Only match if we\'re not at the end of a tag. 
    .         # Match any character 
    )*         # any number of times. 
    [email protected]\.com     # Match the required email address 
    (?:(?!End\ of\ a\ transaction).)* # and the rest of the tag. 
    ^        # Then match (at the start of a line) 
    End\ of\ a\ transaction\.\n  # the closing tag./smx', 
    $subject, $result, PREG_PATTERN_ORDER); 
$result = $result[0]; 

測試它live on regex101.com

0

使用s修改,使.匹配換行符:

(?s)Start((?!Start).)*email1\@gmail\.com(.*?)End([^\n]*) 

((?!Start).)*在我們步入由*修改,以確保我們在一個塊在每個位置斷言負前瞻一次。

Live demo

+0

懶惰量詞是不夠的,讓正則表達式越過邊界「交易結束」:https://regex101.com/r/mU4vW8/2 –

+0

@TimPietzcker那是因爲你正在使用' g'修飾符,它必須做到最好。 – revo

+0

不可以。「g」修飾符的意思是「查找所有匹配,而不僅僅是第一個匹配」。 –

相關問題