如何使用 findall 提取元组?
How to extract tuples using findall?
我正在尝试从 url 中提取元组,并且我已经成功地提取了 string text 和 元组使用re.search(pattern_str, text_str)
。但是,当我尝试使用 re.findall(pattern_str, text_str)
.
提取元组列表时卡住了
文本看起来像:
<li>
<a href="11111">
some text 111
<span class="some-class">
#11111
</span>
</a>
</li><li>
<a href="22222">
some text 222
<span class="some-class">
#22222
</span>
</a>
</li><li>
<a href="33333">
some text 333
<span class="some-class">
#33333
</span>
</a>
... # repeating
...
...
我正在使用以下模式和代码来提取元组:
text_above = "..." # this is the text above
pat_str = '<a href="(\d+)">\n(.+)\n<span class'
pat = re.compile(pat_str)
# following line is supposed to return the numbers from the 2nd line
# and the string from the 3rd line for each repeating sequence
list_of_tuples = re.findall(pat, text_above)
for t in list_of tuples:
# supposed to print "11111 -> blah blah 111"
print(t[0], '->', t[1])
也许我正在尝试一些奇怪且不可能的事情,也许最好使用原始字符串操作来提取数据...但是万一有解决方案呢?
您的正则表达式没有考虑 \n
和 <span
之间的空格(缩进)。 (而且你想要捕获的行开头的空格也不是,但这不是什么大问题。)要修复它,你可以添加一些 \s*
:
pat_str = '<a href="(\d+)">\n\s*(.+)\n\s*<span class'
按照评论中的建议,使用 html 解析器,例如 BeautifulSoup:
from bs4 import BeautifulSoup
h = """<li>
<a href="11111">
some text 111
<span class="some-class">
#11111
</span>
</a>
</li><li>
<a href="22222">
some text 222
<span class="some-class">
#22222
</span>
</a>
</li><li>
<a href="33333">
some text 333
<span class="some-class">
#33333
</span>
</a>"""
soup = BeautifulSoup(h)
您可以获得 href 和 previous_sibling 到跨度:
print([(a["href"].strip(), a.span.previous_sibling.strip()) for a in soup.find_all("a")])
[('11111', u'some text 111'), ('22222', u'some text 222'), ('33333', u'some text 333')]
或者来自锚点的 href 和第一个内容:
print([(a["href"].strip(), a.contents[0].strip()) for a in soup.find_all("a")])
或使用 .find(text=True)
仅获取标签文本,而不是从子项中获取。
[(a["href"].strip(), a.find(text=True).strip()) for a in soup.find_all("a")]
此外,如果您只想要列表标签内的锚点,您可以专门解析那些:
[(a["href"].strip(), a.contents[0].strip()) for a in soup.select("li a")]
我正在尝试从 url 中提取元组,并且我已经成功地提取了 string text 和 元组使用re.search(pattern_str, text_str)
。但是,当我尝试使用 re.findall(pattern_str, text_str)
.
文本看起来像:
<li>
<a href="11111">
some text 111
<span class="some-class">
#11111
</span>
</a>
</li><li>
<a href="22222">
some text 222
<span class="some-class">
#22222
</span>
</a>
</li><li>
<a href="33333">
some text 333
<span class="some-class">
#33333
</span>
</a>
... # repeating
...
...
我正在使用以下模式和代码来提取元组:
text_above = "..." # this is the text above
pat_str = '<a href="(\d+)">\n(.+)\n<span class'
pat = re.compile(pat_str)
# following line is supposed to return the numbers from the 2nd line
# and the string from the 3rd line for each repeating sequence
list_of_tuples = re.findall(pat, text_above)
for t in list_of tuples:
# supposed to print "11111 -> blah blah 111"
print(t[0], '->', t[1])
也许我正在尝试一些奇怪且不可能的事情,也许最好使用原始字符串操作来提取数据...但是万一有解决方案呢?
您的正则表达式没有考虑 \n
和 <span
之间的空格(缩进)。 (而且你想要捕获的行开头的空格也不是,但这不是什么大问题。)要修复它,你可以添加一些 \s*
:
pat_str = '<a href="(\d+)">\n\s*(.+)\n\s*<span class'
按照评论中的建议,使用 html 解析器,例如 BeautifulSoup:
from bs4 import BeautifulSoup
h = """<li>
<a href="11111">
some text 111
<span class="some-class">
#11111
</span>
</a>
</li><li>
<a href="22222">
some text 222
<span class="some-class">
#22222
</span>
</a>
</li><li>
<a href="33333">
some text 333
<span class="some-class">
#33333
</span>
</a>"""
soup = BeautifulSoup(h)
您可以获得 href 和 previous_sibling 到跨度:
print([(a["href"].strip(), a.span.previous_sibling.strip()) for a in soup.find_all("a")])
[('11111', u'some text 111'), ('22222', u'some text 222'), ('33333', u'some text 333')]
或者来自锚点的 href 和第一个内容:
print([(a["href"].strip(), a.contents[0].strip()) for a in soup.find_all("a")])
或使用 .find(text=True)
仅获取标签文本,而不是从子项中获取。
[(a["href"].strip(), a.find(text=True).strip()) for a in soup.find_all("a")]
此外,如果您只想要列表标签内的锚点,您可以专门解析那些:
[(a["href"].strip(), a.contents[0].strip()) for a in soup.select("li a")]