如何使用正则表达式从HTML中解析数字?

52

我想在Python中编写一个简单的正则表达式,从HTML中提取数字。HTML示例如下:

Your number is <b>123</b>

现在,我该如何提取“123”,即在字符串“您的号码是”后面第一个加粗文本的内容?


文本“Your number is”实际上是否在任何标签内? - Jon Clements
4
好的,我会尽力进行翻译。以下是需要翻译的内容:相关链接:https://dev59.com/X3I-5IYBdhLWcg3wq6do - Endophage
1
@Endophage:元数据相关 - georg
假设 SO 上的大多数问题(如果不是全部)都是更大问题的小测试示例,因此非常相关。该 OP 想使用正则表达式解析 HTML...请注意,我没有链接那篇怒骂文章,只链接了问题。 - Endophage
2
我建议使用lxml来解析HTML。 - 18bytes
10个回答

66
import re
m = re.search("Your number is <b>(\d+)</b>",
      "xxx Your number is <b>123</b>  fdjsk")
if m:
    print m.groups()[0]

2
抱歉表述不够清晰,但我使用了一个稍微修改过的版本,对我来说是有效的。 re.search("Your number is <b>([a-zA-Z_][a-zA-Z_0-9]*)</b>",loginData) - Saqib

26

假设有 s = "Your number is <b>123</b>",则:

import re 
m = re.search(r"\d+", s)

这将起作用并给你

m.group()
'123'

这个正则表达式在字符串中寻找一个或多个连续的数字。

请注意,在这种特定情况下,我们“知道”会有数字序列,否则您将需要测试re.search()的返回值,以确保m包含有效的引用,否则m.group()将导致AttributeError:异常。

当然,如果您要处理大量的HTML,建议您认真考虑BeautifulSoup - 它专门用于处理HTML等内容。整个想法是使用BeautifulSoup避免使用字符串操作或正则表达式进行手动解析。


2
为什么要踩?据我所知,这是功能性的并且符合OP的要求。如果有建设性的反馈,我很乐意纠正任何错误或改进我的答案。然而,没有解释的踩不会对OP、SO或我有所帮助。 - Levon
1
嘿,我们都犯过这种错误。至于那个踩的人,可能是希望得到更健壮的代码吧?如果在123之前有任何数字,当前代码将失败。 - DSM
@DSM :-) .. 是的,我同意,这是一个狭窄的解决方案,实际上只针对特定的问题。在这种情况下,测试re.search()的返回值也不是必要的,但应该这样做。 - Levon
1
我认为OP不想要数字。他们的要求非常明确:“在字符串“Your number is”之后第一个粗体文本的内容”。 - georg
1
@thg435 .. 它说“我怎么提取123,”.. 和“..从HTML中提取一个数字”.. 这就是我做的。我有什么遗漏吗? - Levon
@thg435 听起来不错。但我没有看到歧义或其他解释,第一个加粗的文本不是在字符串“Your number is”之后显示数字123吗?我们可能有不同的阅读理解(我认为所有其他的解决方案也都集中于获取123)。是的,希望OP能告诉我们答案。 - Levon

12
import re
x = 'Your number is <b>123</b>'
re.search('(?<=Your number is )<b>(\d+)</b>',x).group(0)

这段代码搜索的是紧随字符串“Your number is”之后的数字。


8
如果你只想要123,那么难道不应该使用.group(1)吗? - DSM

5
import re
print re.search(r'(\d+)', 'Your number is <b>123</b>').group(0)

4
最简单的方法就是提取数字(数值)。
re.search(r"\d+",text)

2
import re
found = re.search("your number is <b>(\d+)</b>", "something.... Your number is <b>123</b> something...")

if found:
    print found.group()[0]

这里的 (\d+) 是一个分组,因为只有一个分组,所以使用 [0]。当有多个分组时应该使用 [分组索引]


2
val="Your number is <b>123</b>"

选项:1

m=re.search(r'(<.*?>)(\d+)(<.*?>)',val)

m.group(2)

Option : 2

re.sub(r'([\s\S]+)(<.*?>)(\d+)(<.*?>)',r'\3',val)

1

要将其提取为Python列表,可以使用findall

>>> import re
>>> string = 'Your number is <b>123</b>'
>>> pattern = '\d+'
>>> re.findall(pattern,string)
['123']
>>>

0
您可以使用以下示例来解决您的问题:
import re

search = re.search(r"\d+",text).group(0) #returns the number that is matched in the text

print("Starting Index Of Digit", search.start())

print("Ending Index Of Digit:", search.end())

0
import re
x = 'Your number is <b>123</b>'
output = re.search('(?<=Your number is )<b>(\d+)</b>',x).group(1)
print(output)

1
欢迎来到StackOverflow。虽然这可能回答了问题,但解释一下你的代码会更有帮助。 - Dominik
这是对@muffel的回答的更正,并应该承认该来源。 - Jeremy Caney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接