繁体   English   中英

Python正则表达式findall捕获重复的组

[英]Python regex findall to capture repeated groups

上下文

我正在使用python regex解析某些HTML,因为它们太破损而无法使用更适合那些任务的处理器(例如,选择器)。 我要解析的HTML的摘录如下所示:

     <LI><B>First list title</B> Additional info <UL> <LI><I>List element 1</I> additional info </UL> <LI><B>Second list title</B> Additional info <UL> <LI><I>List element 1</I> additional info1 <LI><I>List element 2</I> additional info2 <LI><I>List element 3</I> additional info3 <LI><I>List element 4</I> additional info4 </UL> <!-- many more elements like the ones above --> 

我需要捕获List标题(和其他信息),并且对于每个标题,它还具有所有嵌套元素及其附加信息。

途径

import regex as re

re.findall

reg = re.compile("<li><b>(.*)\n\s*<ul>\n(\s*<li>.+\n)+\s*</ul>", re.IGNORECASE)
g_info = re.findall(reg, response.body)

如果在上面的示例中查看info g_info,我们将看到对于具有一个list元素的用户来说是很好的:

g_info[0] <- ('First list title</B> Additional info', "  <LI><I>List element 1</I> additional info\n")

但是,当有多个子列表元素时,仅获得最后一个。

g_info[1] <- ('Second list title</B> Additional info', "  <LI><I>List element 4</I> additional info4\n")

我希望它是这样的:

g_info[1] <- ('Second list title</B> Additional info', "  <LI><I>List element 1</I> additional info1\n", "  <LI><I>List element 2</I> additional info2\n", ...)

研究和捕获

使用相同的正则表达式,我可以使用.captures函数来捕获所有元素。 我将对其进行微调,使其适用于以下示例:

reg = re.compile("<li><b>(.*)\n\s*<ul>\n(\s*<li>.+\n){2,}\s*</ul>", re.IGNORECASE)
g_info = re.search(reg, response.body)

但是这种方式(我将使用另一个更简单的正则表达式进一步解析每个元素以获得我想要的东西),我只会得到第一个匹配项,而不是所有匹配项。

g_info.captures() <-- '<LI><B>Second list title</B> Additional info\n  <UL>\n  <LI><I>List element 1</I> additional info1\n  <LI><I>List element 2</I> additional info2\n ...'

如果我能以这种格式获得所有这些信息,那对我来说就足够了。

re.findall以及其他循环和过滤

我可以使用一个更简单的正则表达式来获取所有这些。 然后,我可以进一步检测出哪个是子元素,哪些不是,因为列表标题始终以粗体标签开头,而其他则不是。

reg = re.compile("(\s*<li>.+\n)", re.IGNORECASE)
g_info = re.findall(reg, response.body)

我得到的是这样的:

g_info[0] <- '\n\n<LI><B>First list title</B> Additional info\n'
g_info[1] <- '\n  <LI><I>List element1</I> additional info\n'
g_info[2] <- '\n\n<LI><B>Second list title</B> Additional info\n'
g_info[3] <- '\n  <LI><I>List element</I> additional info1\n'
g_info[4] <- '  <LI><I>List element2</I> additional info2\n'
g_info[5] <- '  <LI><I>List element3</I> additional info3\n'

解决方案?

我发现的唯一可行的方法是最后一种,恕我直言,这不是很优雅。 您能帮我找到更好的解决方案吗? 谢谢

import re
pattern = re.compile("(?<=<li><b>).*?(?=</ul>)", re.IGNORECASE | re.DOTALL)
print re.findall(pattern, data)

产量

['First list title</B> Additional info\n  <UL>\n  <LI><I>List element 1</I> additional info\n  ',
 'Second list title</B> Additional info\n  <UL>\n  <LI><I>List element 1</I> additional info1\n  <LI><I>List element 2</I> additional info2\n  <LI><I>List element 3</I> additional info3\n  <LI><I>List element 4</I> additional info4\n  ']

正则表达式解析html不是一个好主意,应尽可能避免RegEx匹配打开的标记(XHTML自包含标记除外)

在走那条路之前,我将重新评估“它们太坏了”,并尽力分析/调试它们,请参阅如何在python中解析格式错误的HTML。

暂无
暂无

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

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