我想从一段文字中提取所有链接目标。例如,从以下
开始data1 = '<a href="a"> a (d <a href="b"> f) b (<a href="c">) d <a href="d"> d(<a href="e">)'
我想得到['a','b','c','d','e']。
但是,我想跳过括号中的任何链接,并且在不在括号中的链接之前发生。在第一个不在括号中的链接之后,括号变得无关紧要,我想匹配所有链接。所以,对于字符串
data2 = 'a (d <a href="b"> f) b (<a href="c">) d <a href="d"> d(<a href="e">)'
我想得到['d','e']。
我尝试过使用正则表达式模块。以下表达式捕获所有链接(带括号和不带括号):
regex.match('(?:.*?<a href="([^>])+">)*', data2).captures(1)
如何跳过括号中的初始链接?
答案 0 :(得分:2)
解析HTML并不是一件容易的事,并且使用regexp并不容易,你最好使用像html5lib这样真正优秀的HTML解析器。解析HTML后,您可以使用简单的状态机或任何您喜欢的方式发现有趣的值:
import html5lib
document = html5lib.parse('a (d <a href="b"> f) b (<a href="c">) d <a href="d"> d(<a href="e">)')
tokens = []
for element in document.getiterator():
tokens.append((element.tag[element.tag.index('}')+1:], element))
if element.text is not None:
for char in element.text:
tokens.append(('text', char))
state = 'OUT_OF_PARENTHESIS'
for token_type, value in tokens:
if state == 'OUT_OF_PARENTHESIS':
if token_type == 'a':
state = 'GOT_AN_A_OUT_OF_PARENTHESIS'
print(value.attrib)
continue
if state == 'OUT_OF_PARENTHESIS':
if token_type == 'text' and '(' in value:
state = 'IN_PARENTHESIS'
continue
if state == 'IN_PARENTHESIS':
if token_type == 'text' and ')' in value:
state = 'OUT_OF_PARENTHESIS'
continue
if state == 'GOT_AN_A_OUT_OF_PARENTHESIS':
if token_type == 'a':
print(value.attrib)
答案 1 :(得分:1)
所以基本上任务是在括号内放置链接,然后返回余数中的所有链接。您可以将(恰当命名的)itertools.dropwhile
与正则表达式结合使用。
这是我将如何做到的:
from itertools import dropwhile
def get_links(s):
without_paren = r'<a href="(?P<WITHOUT_PAREN>[^"]+)">'
with_paren = r'\(.*?<a href="(?P<WITH_PAREN>[^"]+)">.*?\)'
master_pattern = with_paren + '|' + without_paren # try with_paren first
it = re.finditer(master_pattern, s)
# Drop matches in `it` until we hit the first without_paren match
# and yield every match from there onwards
for mo in dropwhile(lambda mo: mo.lastgroup == 'WITH_PAREN', it):
yield mo.group(mo.lastgroup)
尝试使用您的数据:
>>> print(list(get_links(data1)))
['a', 'b', 'c', 'd', 'e']
>>> print(list(get_links(data2)))
['d', 'e']
人们通常会告诉你使用专门的库解析HTML等,它们通常都是正确的。 HTML不是一种常规语言,正则表达式在其完全复杂性方面无法真正处理它。但你似乎正在处理一个常规的&#34;这里有一些数据,正则表达式可能正常工作。