2017-02-16 96 views
0

我正在解析一个HTML文件,并希望匹配两个字符序列之间的所有内容:Sent:<br>标记。为什么我的正则表达式不适用于BeautifulSoup?

我见过几个非常相似的问题,并尝试了所有的方法,但都没有为我工作,可能是因为我是新手,并且做了一些非常简单的事情。

这里是我的相关代码:

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) 

,我也试着为这些我正则表达式:a = re.findall(r'Sent:/^(.*?)<br>/', soup.text)[0]a = re.findall(r'Sent:/^[^<br>]*/', soup.text)[0]

但我不断收到错误list index out of range ....但即使我删除在[0]我上线d = parser.parse(a)错误AttributeError: 'list' object has no attribute 'read' ....只有[]印刷作为print(a)

结果下面是HTML的相关版块:

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

回答

1

这个问题并不是你的正则表达式,但是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,其在documentation of 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/>)') 
+0

哦,好吧,这很有道理,我打印出来,看到你在说什么关于,现在的事情是,我没有评论它下面的'd = parser.parse(a)'和'print()'语句,并且它们仍然失败,出现错误“ValueError:Unknown string format”一直困扰着我一段时间 – theprowler

+1

公平地说,我不明白“parser.parse”是什么意思。什么是“解析器”?我知道一个名为“dateparser”的模块,但我无法安装它尝试。 –

+0

那么我被告知导入'从dateutil导入解析器'....这种方式我使用RegEx来捕获'发送:'后的所有内容,然后'parser()'识别并捕获之后捕获的东西内的日期'发送:'......但是某些电子邮件发生了什么,特别是这个,没有'\ n'字符,因此RegEx被搞乱了......所以我注意到在HTML中有一个'
'在日期信息的末尾,所以我发布了这个问题....现在我发现我基本处于同样的窘境 – theprowler

1

可以请你在下面的一个替代你的正则表达式查找的关键条款,然后他们告诉我如果有什么错误,您正在接受之间什么?

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

只显示'[]' – theprowler

+0

请尝试在regxr.com上。我刚刚做完。为我工作。在这种情况下,这个问题似乎不是正则表达式。 – leo

+0

那么这不是一个好消息......任何想法为什么它会失败呢?此代码在另一个HTML电子邮件完美工作,但后来我试图运行它在这一个,所有这些错误不断出现我的企图只捕捉日期 – theprowler

1

试试这个。它还会考虑<br>标签是否包含斜杠。

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

所有打印的是[]'以及:( – theprowler

1

你不需要通常的斜线逃脱:

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

话虽这么说,你应该检查输出(或至少使用try /除外)试图获得一个前值从中。

相关问题