了解用于在html中查找字符串之间的字符串的正则表达式模式

时间:2015-09-10 02:08:18

标签: python regex python-2.7 non-greedy

我有以下html文件:

<!-- <div class="_5ay5"><table class="uiGrid _51mz" cellspacing="0" cellpadding="0"><tbody><tr class="_51mx"><td class="_51m-"><div class="_u3y"><div class="_5asl"><a class="_47hq _5asm" href="/Dev/videos/1610110089242029/" aria-label="Who said it?" ajaxify="/Dev/videos/1610110089242029/" rel="theater">

为了在videos//"之间提取数字,请使用我发现的以下方法:

import re 

Source_file = open('source.html').read()
result = re.compile('videos/(.*?)/"').search(Source_file)
print result

我已经尝试使用谷歌搜索解释(.*?)在这个特定实现中的确切运作方式,但我还不清楚。有人可以向我解释一下吗?这是什么被称为&#34;非贪婪&#34;比赛?如果是,那是什么意思?

1 个答案:

答案 0 :(得分:4)

此上下文中的?是重复运算符(+*?)上的特殊运算符。在可用的引擎中,这会导致重复 lazy 非贪婪不情愿或其他此类术语。通常重复是贪婪的,这意味着它应尽可能匹配。因此,在大多数现代perl兼容引擎中,您有三种类型的重复:

.*  # Match any character zero or more times
.*? # Match any character zero or more times until the next match (reluctant)
.*+ # Match any character zero or more times and don't stop matching! (possessive)

可在此处找到更多信息:http://www.regular-expressions.info/repeat.html#lazy表示不情愿/懒惰,此处:http://www.regular-expressions.info/possessive.html表示占有欲(我将在此答案中跳过讨论)。

假设我们有字符串aaaa。我们可以将所有a与/(a+)a/匹配。从字面上看这是

  

匹配一个或多个a后跟a

这将匹配aaaa。正则表达式是贪婪的,并且将尽可能多地匹配a。第一个子匹配是aaa

如果我们使用正则表达式/(a+?)a,那么

  

不情愿匹配一个或多个a s后跟a
  
  匹配一个或多个a,直到我们到达另一个a

也就是说,只匹配我们需要的东西。因此,在这种情况下,匹配为aa,第一个子匹配为a。我们只需要匹配一个a来满足重复次数,然后是a

当使用正则表达式匹配html标签,引号和类似内容(通常为快速和脏操作保留)时,这会出现很多。也就是说使用正则表达式从非常大且复杂的html字符串中提取或带有转义序列的带引号的字符串可能会导致很多问题,但它对于特定用例来说非常好。所以在你的情况下我们有:

/Dev/videos/1610110089242029/

表达式需要与videos/匹配,后跟零个或多个字符,后跟/"。如果只有一个视频网址,那就没关系了。

但是我们有

/videos/1610110089242029/" ... ajaxify="/Dev/videos/1610110089242029/"

没有不情愿,正则表达式将匹配:

1610110089242029/" ... ajaxify="/Dev/videos/1610110089242029

尝试尽可能匹配,/"满足.就好了。由于不情愿,匹配在第一个/"处停止(实际上它会回溯,但您可以单独阅读)。因此,您只能获得所需网址的一部分。