编程语言
首页 > 编程语言> > python – 与正则表达式的复杂非贪婪匹配

python – 与正则表达式的复杂非贪婪匹配

作者:互联网

我正在尝试从HTML表中解析行,其中包含在Python中使用正则表达式的特定值的单元格.我在这个(人为的)例子中的目标是获得带有“牛”的行.

import re

response = '''
<tr class="someClass"><td></td><td>chicken</td></tr>
<tr class="someClass"><td></td><td>chicken</td></tr>
<tr class="someClass"><td></td><td>cow</td></tr>
<tr class="someClass"><td></td><td>cow</td></tr>
<tr class="someClass"><td></td><td>cow</td></tr>
'''

r = re.compile(r'<tr.*?cow.*?tr>', re.DOTALL)

for m in r.finditer(response):
  print m.group(0), "\n"

我的输出是

< tr class =“someClass”>< td>< / td>< td> chicken< / td>< / tr>
 < tr class =“someClass”>< td>< / td>< td> chicken< / td>< / tr>
 < tr class =“someClass”>< td>< / td>< td> cow< / td>< / tr>

< tr class =“someClass”>< td>< / td>< td> cow< / td>< / tr>

< tr class =“someClass”>< td>< / td>< td> cow< / td>< / tr>

虽然我的目标是获得

< tr class =“someClass”>< td>< / td>< td> cow< / td>< / tr>

< tr class =“someClass”>< td>< / td>< td> cow< / td>< / tr>

< tr class =“someClass”>< td>< / td>< td> cow< / td>< / tr>

我明白非贪心?在这种情况下不起作用,因为回溯是如何工作的.我摆弄着负面的外观和前瞻但却无法让它发挥作用.

有人有建议吗?

我知道像Beautiful Soup等解决方案,但问题是关于理解正则表达式,而不是问题本身.

解决人们对不使用HTML正则表达式的担忧.我想要使​​用正则表达式来解决的一般问题是来自

response = '''0randomstuffA1randomstuff10randomstuffA2randomstuff10randomstuffB3randomstuff10randomstuffB4randomstuff10randomstuffB5randomstuff1'''

输出

0randomstuffB3randomstuff1 

0randomstuffB4randomstuff1 

0randomstuffB5randomstuff1 

和randomstuff应解释为随机字符串(但不包含0或1).

最佳答案:

您的问题与贪婪无关,而是与正则表达式引擎尝试从左到右在字符串中的每个位置成功.这就是为什么你总是得到最左边的结果,使用非贪婪的量词不会改变起始位置!

如果您写的内容如下:< tr.*?cow.*?tr>或者0.*?B.*?1(对于你的第二个例子)首先尝试模式:

  <tr class="someClass"><td></td><td>chicken</td></tr>...
# ^-----here

# or

  0randomstuffA1randomstuff10randomstuffA2randomstuff10randomstuffB3ra...
# ^-----here

第一个.*?会吃掉字符直到“牛”或“B”.结果,第一场比赛是:

<tr class="someClass"><td></td><td>chicken</td></tr>
<tr class="someClass"><td></td><td>chicken</td></tr>
<tr class="someClass"><td></td><td>cow</td></tr>

为你的第一个例子,和:

0randomstuffA1randomstuff10randomstuffA2randomstuff10randomstuffB3randomstuff1

为了第二个.

要获得所需的内容,需要使模式在字符串中不需要的位置失败.要做到这一点 .*?因为过于宽容而没用.

例如,您可以禁止< / tr>或者在“牛”或“B”之前发生1.

# easy to write but not very efficient (with DOTALL)
<tr\b(?:(?!</tr>).)*?cow.*?</tr>

# more efficient
<tr\b[^<c]*(?:<(?!/tr>)[^<c]*|c(?!ow)[^<c]*)*cow.*?</tr>

# easier to write when boundaries are single characters
0[^01B]*B[^01]*1

标签:python,regex,non-greedy
来源: https://codeday.me/bug/20190516/1115401.html