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'
丢失了。
这是为什么?如何提取标签之间的内容?
此外,有些人可能会建议我应该使用 lxml
和 BeautifulSoup
,因为我也发现了一些奇怪的事情:
使用此代码:
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>
我想使用 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'
丢失了。
这是为什么?如何提取标签之间的内容?
此外,有些人可能会建议我应该使用 lxml
和 BeautifulSoup
,因为我也发现了一些奇怪的事情:
使用此代码:
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 printsim here
as expected, andBeautifulSoup
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>