鉴于文字:
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
但是返回第1页和第4页。
PAGE(?!.*?PAGE).*?banana
这是尝试向前看,并确保页面和香蕉字之间没有额外的页面,但这没有返回任何内容。
(?<=PAGE).*(?=banana)
借鉴Regex, get entire string between two keywords。这将返回PAGE 1,匹配最后一个香蕉和第一个PAGE之间的所有内容。
我认为环顾四周就是答案,但我无法理解如何将PAGE#与香蕉相匹配,但只有PAGE#香蕉才开启。我该怎么做?
答案 0 :(得分:1)
试试这个正则表达式。
正则表达式: PAGE (\d+)\s[^ ]*(?=banana)[^ ]*\n
要使用的标志:
g
进行全球搜索。
s
允许.
搜索换行。
使用\1
或$1
抓取第一个群组。
的 Regex101 Demo 强>
答案 1 :(得分: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']}
答案 2 :(得分:0)
答案 3 :(得分: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
(?:.(?!^$))*?
)
答案 4 :(得分:-1)
这有效:
PAGE(?:(?PAGE)。)*?香蕉
感谢Wiktor关于使用驯化贪婪令牌解决方案的评论,我用Google搜索并找到了此页面:http://www.rexegg.com/regex-quantifiers.html#tempered_greed
全部谢谢!