从段落中提取地址的正则表达式
好吧,这个问题有点麻烦。我正在用Python进行数据抓取,想从几行标记不太好的HTML中提取一个地址。下面是格式的一个示例:
256-555-5555<br/>
1234 Fake Ave S<br/>
Gotham (Lower Ward)<br/>
我只想提取 1234 Fake Ave S, Gotham
。有没有什么好主意?我昨晚一直在写正则表达式,现在脑袋都快炸了……
编辑:
关于数据可能到达的情况,我想多说几句。有时候第一行会出现,有时候不会。我见过的所有地址中都有“Ave”、“Way”、“St”,不过我更希望不把这些作为选择的标准,因为我不确定它们总是这样。第二行和第三行是电话(或者可能是电子邮件或网站):
我想要的东西是:
- 选择倒数第二行的所有内容(如果有三行就是第二行,如果只有两行且没有电话号码就是第一行)。
- 选择最后一行中不在括号里的所有内容。
- 把倒数第二行和最后一行结合起来,中间加一个“, ”。
我正在使用Scrapy来获取HTML代码。地址都在同一个div里,我想用正则表达式进一步把数据分成合适的部分。现在我就是不知道怎么做到这一点。
编辑2:
根据Ofir的评论,我应该提到我已经写了表达式来隔离电话号码和括号部分。
电话号码(或可能的电子邮件或网站):
((1[-. ])?[0-9]{3}[-. ])?\(?([0-9]{3}[-. ][A?([0-9]{4})|([\w\.-]+@[\w\.-]+)|(www.+)|([\w\.-]*(?:com|net|org|us))
括号部分:
\((.*?)\)
我不太确定怎么用这些来构建一个“除了这些以外”的表达式。
3 个回答
根据我对你问题的理解,我觉得你可能走了错误的解决方向。
正则表达式并不是一种神奇的工具,不能从一堆杂乱无章的文本中提取出有用的数据。它只能从那些有一定结构的文本中提取数据,这些结构部分就像锚一样,帮助我们定位那些可变的部分。
在你的处理过程中,我觉得你首先是把可能的电话号码和地址从1到2行中分离出来了。但这样做,你失去了很多信息:在这部分之前和之后的内容是很重要的锚点信息,你不应该在去掉这些信息后再去寻找剩下的部分。
而且,我猜想你不仅仅想提取一个电话号码和一个地址:你可能还想提取这部分之前和之后的其他信息。用一个设计得当的正则表达式,你可以一次性捕获所有你需要的内容。
所以,请提供更多的文本,包含足够多的字符在你想要提取的部分之前和之后,这样才能写出一个正确且简单的正则表达式策略,来捕获你想要的所有数据。triplee已经问过你这个问题了,但你没有提供,为什么呢?
这个代码的目的是从字符串中提取最后两行内容:
>>> s="""256-555-5555<br/>
... 1234 Fake Ave S<br/>
... Gotham (Lower Ward)<br/>
... """
>>> m = re.search(r'((?!</br>).*)<br/>\n((?!</br>).*)<br/>$)', s)
>>> print m.group(1)
1234 Fake Ave S
去掉括号的部分最好单独写一行代码,这样不会让正则表达式变得更复杂。
在你的情况下,可能更简单的方法是先关注你不想要的东西:
- HTML标签(比如
<br>
) - 电话号码
- 括号里的所有内容
这些都可以用简单的规则轻松找到,这样就能更容易地构建一个规则来匹配其他内容(假设是地址)。