ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-05-16 13:46:06  阅读:214  来源: 互联网

标签:python regex non-greedy


我正在尝试从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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有