2016-03-14 57 views
1

中的文字:正則表達式搜索詞兩者是相同

PAGE 1 
apple 

PAGE 2 
apple 
banana 

PAGE 3 
orange 

PAGE 4 
banana 

PAGE 5 
pear 

PAGE 6 
apple 
orange 
banana 
pea 

我希望有一個正則表達式,會告訴我每一個頁面一個香蕉上,這是第2頁和4

事情我已經嘗試:

PAGE.*?banana.*?PAGE 

但返回PAGE 1和4

PAGE(?!.*?PAGE).*?banana 

這是一個嘗試向前看,並確保頁面和香蕉字之間沒有額外的頁面,但這沒有返回。

(?<=PAGE).*(?=banana) 

借來自Regex, get entire string between two keywords。這是返回PAGE 1,匹配最後一個香蕉和第一頁之間的所有內容。

我認爲環顧四周就是答案,但我無法圍繞如何匹配PAGE#和香蕉,但只有PAGE#香蕉。我怎麼做?

+0

您需要編號或整個塊? – andlrc

+1

你只需要一個溫和的貪婪標記解決方案:['PAGE \ d + \ n((?:(?!\ bbanana \ b | \ nPAGE \ d + \ n)。)* \ bbanana \ b(?:(?!\ (* = \ nPAGE \ d + \ n | $)'](https://regex101.com/r/gE1oN3/1)。 –

+0

我只需要這個號碼。 – Mike

回答

1

試試這個正則表達式。

正則表達式:PAGE (\d+)\s[^ ]*(?=banana)[^ ]*\n

標誌使用:

  • g全局搜索。

  • s允許.搜索換行符。

捕獲使用\1$1第一組。

Regex101 Demo

+0

這工作,非常感謝你! – Mike

+0

我希望你的數據格式保持不變,否則只有**一個空間毀了這一切**。 :D – 2016-03-14 20:58:07

+0

這是一個很好的觀點。 – Mike

0

嘗試這種模式

(?<=PAGE)(\d+)(?=(?:[^P]|\bP(?!AGE\b))*\bbanana\b) 

Demo

1

re.finditer大用途:

txt="""\ 
PAGE 1 
apple 

PAGE 2 
apple 
banana 

PAGE 3 
orange 

PAGE 4 
banana 

PAGE 5 
pear""" 

import re 

tgt='banana' 

for m in re.finditer(r'^PAGE\s+(\d+)\s+([\s\S]+?)(?=^PAGE|\Z)', txt, re.M): 
    if re.search(r'(?i){}'.format(tgt), m.group(2)): 
     print '"{}" found on Page {}'.format(tgt, m.group(1)) 

打印:

"banana" found on Page 2 
"banana" found on Page 4 

同樣的技術可以產生每個水果的映射上頁:

di={} 
for m in re.finditer(r'^PAGE\s+(\d+)\s+([\s\S]+?)(?=^PAGE|\Z)', txt, re.M): 
    for fruit in m.group(2).split(): 
     di.setdefault(fruit, []).append(m.group(1)) 
>>> di 
{'orange': ['3'], 'pear': ['5'], 'apple': ['1', '2'], 'banana': ['2', '4']} 
0

只給另一種選擇,這會工作,以及:

^PAGE\s+(?P<page>\d+)[\n\r] # match PAGE + whitespace + digit at the beginning of a line 
(?s:      # open a non-capturing, single-line parenthesis 
    (?:.(?!^$))*?   # make not to match an empty line (lazily) 
    \bbanana\b    # look for banana with word boundaries 
    (?:.(?!^$))*? 
) 

a demo on regex101.com