繁体   English   中英

为什么我的正则表达式不适用于BeautifulSoup?

[英]Why my regex doesn't work with BeautifulSoup?

我正在解析一个HTML文件,并希望匹配两个字符序列之间的所有内容: Sent:<br>标签。

我已经看到了几个非常相似的问题,并尝试了所有方法,但没有一个对我有用,可能是因为我是新手,并且做错了非常简单的事情。

这是我的相关代码:

for filename in os.listdir(path): #capture email year, month, day
    file_path = os.path.join(path, filename)
    if os.path.isfile(file_path):
        with open(file_path, 'r') as f:
            html = f.read()
            soup = BeautifulSoup(html, 'html.parser')
            a = re.findall(r'Sent:/.+?(?=<br>)/', soup.text)[0]
            #a = re.findall(r'Sent:(.*)', soup.text)[0]
            print(a)
            d = parser.parse(a)
            print("year:", d.year)
            print("month:", d.month)
            print("day:", d.day)

并且我还在RegEx上尝试过这些: a = re.findall(r'Sent:/^(.*?)<br>/', soup.text)[0]a = re.findall(r'Sent:/^[^<br>]*/', soup.text)[0]

但是我一直使错误list index out of range ..但是即使删除[0]我也会收到错误AttributeError: 'list' object has no attribute 'read'd = parser.parse(a) ....仅打印[]作为print(a)结果print(a)

这是相关的HTML块:

<b>Sent:</b> Friday, June 14, 2013 12:07 PM<br><b>To:</b> David Leveille<br><b>Subject:</b> 

您能否用以下查找正则表达式的正则表达式替换正则表达式,然后在它们之间输入任何内容,并告诉我如果您现在收到任何错误,请问我?

a=re.findall(r"Sent:(.*?)<br>", soup.text)[0]

尝试这个。 它还考虑了<br>标记是否包含斜杠。

/Sent:(.*?)<\/*br>/

您不需要通常的斜线转义:

a = re.findall(r"Sent:(.*?)<br>", soup.text)[0]

话虽如此,您可能应该在尝试从输出中获取值之前检查输出(或至少使用try / except)。

问题实际上不是您的正则表达式,而是BeautifulSoup解析HTML(毕竟是它的工作)并更改其内容的事实。 例如,您的<br>将转换为<br/> 另一点:soup.text会删除所有标签,因此您的正则表达式将不再起作用。

试试这个脚本会更清楚:

from bs4 import *
import re
from dateutil import parser

pattern = re.compile(r'Sent:(.+?)(?=<br/>)')

with open("myfile.html", 'r') as f:
        html = f.read()
        print("html: ", html)
        soup = BeautifulSoup(html, 'lxml')
        print("soup.text: ", soup.text)
        print("str(soup): ", str(soup))
        a = pattern.findall(str(soup))[0]
        print("pattern extraction: ", a)

对于第二部分:由于日期字符串在形式上不正确(由于初始<br/> ),因此应添加参数fuzzy=True ,如dateutil文档中所述

d = parser.parse(a, fuzzy=True)
print("year:", d.year)
print("month:", d.month)
print("day:", d.day)

另一个解决方案是使用更精确的正则表达式。 例如 :

pattern = re.compile(r'Sent:</b>(.+?)(?=<br/>)')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM