re.search 仅 return 部分字符串

re.search only return part of strings

我想使用 Python re 模块获取 <script>...</script> 标签之间的内容。我使用 re.search(r'<script>[\S\s]*</script>', myhtml) 来搜索内容,其中 [\S\s]* 表示搜索任何字符串。但是这个函数的行为很奇怪,它只是 returns 部分想要的内容。所以我举个小例子来说明我的意思。

import re
re.search('[\S\s]*','<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traitional//E')

期望的结果应该是 '<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traitional//E',这是原始输入字符串。但是,它会打印 <_sre.SRE_Match object; span=(0, 56), match='<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traiti>。可以看出,字符串的最后一部分,即 'onal//E' 丢失了。

这是为什么?如何提取标签之间的内容?

此外,有些人可能会建议我应该使用 lxmlBeautifulSoup,因为我也发现了一些奇怪的事情:

使用此代码:

from lxml import etree
rr='''
<script>
<div>
im here
</div>
</script>

'''
html = etree.HTML(rr, etree.HTMLParser())
print(html.xpath('//div//text()'))

以上代码没有打印任何内容。如果我将 <script> 更改为 <script1>,那么它会按预期打印 im here,并且 BeautifulSoup 具有相同的行为。

要添加到 ,您正在做 .search,其中 return 是 re.Match class,其中有 0 到多个个体组火柴。这些数据比 .findall.

有更多的数据,例如匹配的起始索引及其长度
>>> match = re.search('[\S\s]*','<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traitional//E')
>>> match
<re.Match object; span=(0, 56), match='<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traiti>
>>> dir(match)
['__class__', '__class_getitem__', '__copy__', '__deepcopy__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 'span', 'start', 'string']

您也可以使用 .findall(),这将 return 一个列表。

我还建议在传递正则表达式模式时始终使用 r'' 字符串。

>>> re.search(r'[\S\s]*','<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traitional//E').group(0)
'<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traitional//E'
>>> re.findall(r'[\S\s]*','<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traitional//E')
['<!DOCTYPE HTML PUBLIC "-<!DO/W3C//DTD C 1.0Traitional//E', '']

您的第一个问题已经得到解决。

第二个问题的答案:

The above code prints nothing. If I change <script> to <script1>, then it prints im here as expected, and BeautifulSoup has the same behavior.

这是因为 <div> 实际上 <script> 标签。

根据您提供的 HTML:

<script>
<div>
im here
</div>
</script>

如果我们对其进行美化,您会清楚地看到 <div> 标签 <script>:

<script>
  <div>
  im here
  </div>
</script>

因此,要使用 BeautifulSoup 获得 <div>,您可以使用 next_element 属性:

soup = BeautifulSoup(html, "html.parser")
print(soup.find("script").next_element)

输出:

<div>
im here
</div>