1

我是正则表达式的新手,这让我很困惑。

在下面的示例中,我想提取facebook.com/pages/Dr-Morris-Westfried-Dermatologist/176363502456825?id=176363502456825&sk=info. 我已经阅读了惰性量词和lookbehinds,但我仍然无法拼凑出正确的正则表达式。我希望facebook.com\/.*?sk=info能工作,但它捕捉到了太多。你们能帮忙吗?

<i class="mrs fbProfileBylineIcon img sp_2p7iu7 sx_96df30"></i></span><span class="fbProfileBylineLabel"><span itemprop="address" itemscope="itemscope" itemtype="http://schema.org/PostalAddress"><a href="https://www.facebook.com/pages/Dr-Morris-Westfried-Dermatologist/176363502456825?sk=page_map" target="_self">7508 15th Avenue, Brooklyn, New York 11228</a></span></span></span><span class="fbProfileBylineFragment"><span class="fbProfileBylineIconContainer"><i class="mrs fbProfileBylineIcon img sp_2p7iu7 sx_9f18df"></i></span><span class="fbProfileBylineLabel"><span itemprop="telephone">(718) 837-9004</span></span></span></div></div></div><a class="title" href="https://www.facebook.com/pages/Dr-Morris-Westfried-Dermatologist/176363502456825?id=176363502456825&amp;sk=info" aria-label="About Dr. Morris Westfried - Dermatologist">
4

4 回答 4

4

尽管我很喜欢正则表达式,但这是一个 html 解析任务:

>>> from bs4 import BeautifulSoup
>>> html = .... # that whole text in the question
>>> soup = BeautifulSoup(html)
>>> pred = lambda tag: tag.attrs['href'].endswith('sk=info')
>>> [tag.attrs['href'] for tag in filter(pred, soup.find_all('a'))]
['https://www.facebook.com/pages/Dr-Morris-Westfried-Dermatologist/176363502456825?id=176363502456825&sk=info']
于 2014-03-29T23:05:14.160 回答
3

这有效:)

facebook\.com\/[^>]*?sk=info

正则表达式可视化

调试演示

只有.*它找到第一个 facebook.com,然后继续直到sk=info. 由于facebook.com之间还有另一个,因此您将它们重叠。

你不想要的唯一的东西是 a >(或<,在其他字符中),因此将任何内容更改  为  a 之外>的任何内容都会根据需要找到facebook.com 最接近, 的东西sk=info

是的,对 HTML 使用正则表达式只能用于基本任务。否则,使用解析器。

于 2014-03-29T23:00:21.660 回答
2

为什么你的模式不起作用:

您的模式不起作用,因为正则表达式引擎在字符串中从左到右尝试您的模式。

当正则表达式引擎遇到facebook.com\/字符串中的第一个时,并且由于您使用after,正则表达式引擎会将所有字符(包括或或空格).*?添加到(可能的)匹配结果中,直到找到(因为可以匹配除换行符之外的任何字符) .">sk=info.

这就是为什么 fejese 建议将点替换为[^"]或 aliteralmind 建议将其替换为[^>]以使模式在字符串中的此位置(第一个)失败的原因。

如果要处理 html,使用 html 解析器是最简单的方法。但是,对于一次匹配或搜索/替换,请注意,如果 html 解析器提供安全性、简单性,那么它在性能方面是有代价的,因为您需要为单个任务加载文档的整个树。

于 2014-03-30T00:49:40.560 回答
2

问题是您还有另一个 facebook.com 部分。您可以限制.*不匹配",因此它需要保持在一个属性内:

facebook\.com\/[^"]*;sk=info
于 2014-03-29T22:58:48.150 回答