【问题标题】:Can I have a non-greedy regex with dotall?我可以使用 dotall 进行非贪婪的正则表达式吗?
【发布时间】:2012-02-29 22:41:09
【问题描述】:

我想匹配 dotall 和 non-greedy。这就是我所拥有的:

img(.*?)(onmouseover)+?(.*?)a

然而,这并不是不贪婪。此数据与我预期的不匹配:

<img src="icon_siteItem.gif" alt="siteItem" title="A version of this resource is available on siteItem" border="0"></a><br><br></td><td rowspan="4" width="20"></td></tr><tr><td>An activity in which students find other more specific adjectives to 
describe a range of nouns, followed by writing a postcard to describe a 
nice holiday without using the word 'nice'.</td></tr><tr><td>From the resource collection: <a href="http://www.siteItem.co.uk/index.asp?CurrMenu=searchresults&amp;tag=326" title="Resources to help work">Drafting </a></td></tr><tr><td><abbr style="border-bottom:0px" title="Key Stage 3">thing</abbr> | <abbr style="border-bottom:0px" title="Key Stage 4">hello</abbr> | <abbr style="border-bottom:0px" title="Resources">Skills</abbr></td></tr></tbody></table></div></div></td></tr><tr><td><div style="padding-left: 30px"><div><table style="" bgcolor="#DFE7EE" border="0" cellpadding="0" cellspacing="5" width="100%"><tbody><tr valign="top"><td rowspan="4" width="60"><a href="javascript:requiresLevel0(350,350);"><img name="/attachments/3700.pdf" onmouseover="ChangeImageOnRollover(this,'/application/files/images/attach_icons/rollover_pdf.gif')" onmouseout="ChangeImageOnRollover(this,'/application/files/images/attach_icons/small_pdf.gif')" src="small_pdf.gif" alt="Download Recognising and avoiding ambiguity in PDF format" title="Download in PDF format" style="vertical-align: middle;" border="0"></a><br>790.0 k<br>

我不明白为什么。

我认为我在上面的正则表达式中所说的是:

以“img”开头,然后允许 0 个或多个任何字符,包括换行符,然后查找至少 1 个“onmouseover”,然后允许 0 个或多个任何字符,包括换行符,然后是一个“a”

为什么这不符合我的预期?

关键点:必须启用dotall

【问题讨论】:

  • 这似乎工作得很好。我在img name="/attachments/3700.pdf" onmouseover="Cha 上找到了匹配项
  • @jurgemaister 你启用了 dotall 吗?
  • 不,我不知道。猜猜我没有仔细阅读这个问题。在这种情况下,它匹配从第二个字符到我上面提到的点的所有内容。这也是意料之中的。
  • 非贪婪匹配意味着它将在第一个可能的字符处停止。这并不意味着它将从您似乎期望的最后一个可能的字符开始。
  • 你实际上想用这个实现什么?如果我们知道目标和一些示例结果,就更容易提出改进建议......

标签: python regex non-greedy


【解决方案1】:

它是不贪婪的。 是你对非贪婪的理解是不正确的。

正则表达式会总是尝试匹配。

让我展示一个简化的例子来说明非贪婪的实际含义(正如评论所建议的那样):

re.findall(r'a*?bc*?', 'aabcc', re.DOTALL)

这将匹配:

  • 尽可能少地重复“a”(在本例中为 2)
  • 后跟一个“b”
  • 尽可能少地重复“c”(在本例中为 0)

所以唯一的匹配是'aab'

总结一下:

不要使用正则表达式来解析 HTML。有一些图书馆是为这项工作而设计的。 re 不是其中之一。

【讨论】:

  • 作为一个简化的例子,使用re.findall(r'a*?bc*?', 'aabcc', re.DOTALL)
  • 为什么你的例子不只返回b?为什么它可以匹配 'c' 零次但必须匹配 'a' 两次?
  • 找到了我的问题的答案:stackoverflow.com/questions/16633315/…
  • plus1 为您的结论“不要使用正则表达式解析 html”。我正是在尝试这样做。
  • 您可能应该为可用于解析 HTML 的库添加两个示例。 (我知道漂亮的汤效果很好)。
【解决方案2】:

首先,您的正则表达式看起来有点古怪:您说的是匹配“img”,然后是任意数量的字符,“onmouseover”至少一次,但可能重复(例如“onmouseoveronmouseoveronmouseover”),然后是任意数字字符数,后跟“a”。

这应该从img src="icon_ 一直匹配到onmouseover="Cha。这可能不是您想要的,但这是您要求的。

其次,这一点更为重要:

不要使用正则表达式来解析 HTML。

如果你第一次不理解,让我用斜体重复一遍:

不要使用正则表达式来解析 HTML。

最后,让我将您链接到有关该主题的经典魔典:

You can't parse [X]HTML with a regex

【讨论】:

  • @tchirst:您在链接的帖子中创建的是一个 HTML 解析器,它使用正则表达式来构建其词法分析器。它很聪明,很强大。但它不是 是描述HTML 的正则表达式,因为必须单独维护状态(深度)。它作为第三方解析器库很有用,但阻止初学者使用正则表达式解析 HTML 的全部意义在于鼓励他们使用经过测试的、专门构建的解析器库。 HTML 远比初学者编写的单行正则表达式可以安全地捕获要复杂得多。 (另外,喜欢你的书)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2015-08-25
  • 2011-04-27
相关资源
最近更新 更多