如何控制Python的re.findall()在HTML字符串中返回的结果?

0 投票
4 回答
536 浏览
提问于 2025-04-16 20:15

我想要找到所有出现的“Catalina 320”,前提是它们出现在“这些船”这个字符串之前(下面有个简单的例子)。

我已经有了可以找到所有“Catalina 320”的代码,但我不知道怎么在“这些船”这个字符串那里停止。

resultsArray = re.findall(r'<tag>(Catalina 320)</tag>', string, re.DOTALL)

有没有人能帮我解决这个问题?我试着加上‘.+这些船’,但没成功。

谢谢- JD

  Blah blah blah
    <tag>**Catalina 320**</tag>
  Blah
    <td>**Catalina 320**</td>
  Blah Blah 
    <tag>**These boats** are fully booked for the day</tag>
  Blah blah blah
    <tag>Catalina 320</tag>
    <tag>Catalina 320</tag>

4 个回答

0
groups = re.findall(r'(Catalina 320)*.*These boats, r.read(), re.DOTALL)

第一组中的内容会包含Catalina 320比赛的列表。

3

你可以用正则表达式来解决这个问题,但根据你描述的问题,其实不一定需要用到正则表达式见尾注1

你应该使用lxml来解析这个内容...

import lxml.etree as ET
from lxml.etree import XMLParser

resultsArray = []
parser = XMLParser(ns_clean=True, recover=True)
tree = ET.parse('foo.html', parser)   # See End-Note 2
for elem in tree.findall("//"):
    if "These boats" in elem.text:
        break
    elif "Catalina 320" in elem.text:
        resultsArray.append(ET.tostring(elem).strip())


print resultsArray

执行这个后会得到:

[mpenning@Bucksnort ~]$ python foo.py
['<tag>**Catalina 320**</tag>', '<td>**Catalina 320**</td>']
[mpenning@Bucksnort ~]$


尾注:

  1. 你提问的当前版本没有有效的标记,但我假设你有xml或html(这也是你在问题第1版中提供的内容)……我的回答可以处理你写的文本,但假设有某种结构的标记会更合理,所以我使用了以下输入文本,并将其保存在本地,命名为foo.html:

         <body>
    <tag>Blah blah blah</tag>
        <tag>**Catalina 320**</tag>
      <tag>Blah<tag>
        <td>**Catalina 320**</td>
      </tag>Blah Blah </tag>
        <tag>**These boats** are fully booked for the day</tag>
      <tag>Blah blah blah</tag>
        <tag>Catalina 320</tag>
        <tag>Catalina 320</tag>
        </body>
    
  2. 如果你想更小心地处理编码问题,可以在用lxml解析HTML时,使用lxml.soupparser作为备用方案。

from lxml.html import soupparser
# ...
try:
    parser = XMLParser(ns_clean=True, recover=True)
    tree = ET.parse('foo.html', parser)
except UnicodeDecodeError:
    tree = soupparser.parse('foo.html')
2

如果你的问题没有其他背景信息,你可以在第一次出现 'These boats' 之前进行搜索:

re.findall('Catalina 320', string.split('These boats')[0])

撰写回答