Python正则表达式-标识列表中的第一项和最后一项
我需要将一些文本文件转换成HTML代码。我一直在将列表转换为HTML无序列表。示例来源: 文档中的某些文本Python正则表达式-标识列表中的第一项和最后一项,python,regex,Python,Regex,我需要将一些文本文件转换成HTML代码。我一直在将列表转换为HTML无序列表。示例来源: 文档中的某些文本 *项目1 *项目2 *项目3 其他一些文本 输出应为: some text in the document <ul> <li>item 1</li> <li>item 2</li> <li>item 3</li> </ul> some other text 文档中的某些
*项目1
*项目2
*项目3
其他一些文本 输出应为:
some text in the document
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
some other text
文档中的某些文本
- 项目1
- 项目2
- 项目3
其他一些文本
目前,我有:
r = re.compile(r'\*(.*)\n')
r.sub('<li>\1</li>', the_text_document)
r=re.compile(r'\*(.*)\n')
r、 sub(“\1 ”,即“文本”文档)
它创建了一个不带标签的HTML列表。如何识别第一个和最后一个项目,并用
标记将其包围?您可以逐行处理数据。。下面这个又快又脏的解决方案可能会被整理,但对于您的数据来说,它确实起到了作用
with open('data.txt') as inf:
star_count = 0
for line in inf:
line = line.strip()
if not line.startswith('*'):
if star_count == 1:
print'</ul>'
print line
else:
if star_count == 0:
print '<ul>'
star_count = 1
print ' <li>%s</li>' %line.split('*')[1].strip()
以open('data.txt')作为inf的:
星数=0
对于inf中的行:
line=line.strip()
如果不是line.startswith('*'):
如果星号计数=1:
打印“”
打印行
其他:
如果星号计数==0:
打印“”
星数=1
打印'- %s
'%line.split('*')[1].strip()
收益率:
some text in the document
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
some other text
文档中的某些文本
- 项目1
- 项目2
- 项目3
其他一些文本
根据您的数据有多复杂,或者如果您有重复的未编入列表等,这将需要修改,并且您可能希望寻找更通用的解决方案,或者修改此起始代码以满足您的需要,只有您可以决定
更新:
编辑
打印行以清除以前留下的*
。或使用BeautifulSoup
编辑
显然,我必须给你一些关于如何阅读文档的提示
- 打开链接
- 左边有一个大菜单(青色)
- 如果仔细阅读,您会注意到文档分为多个部分
- 东西
- 树中的导航
- 搜索树
- 修改树(明白了)
- 输出(明白了!)
还有更多的事情
Beauty Soup是一个Python库,用于从HTML和XML文件中提取数据。它与您喜爱的解析器配合使用,提供导航、搜索和修改解析树的惯用方法它通常可以为程序员节省数小时或数天的工作
第一句话之后不要停止阅读。。。最后一个很重要,中间是什么。
换句话说,您可以创建一个空文档。。。比如说:
soup = BeautifulSoup("<div></div>")
document = soup.div
如果该行以`*``
ul = document.new_tag('ul')
document.append(ul)
document = ul
然后按文档上的所有li
。。。一旦你阅读完*
,只要弹出父文档,文档就会返回到div。然后继续这样做。。。您甚至可以递归地将ul
插入ul
s
一旦你解析了一切。。。你能行
str(document)
或
编辑
刚意识到你不是在编辑html,而是一个未格式化的文本。。那你可以试试降价
在考虑了一些想法后,我决定使用第二个正则表达式。
因此,基本上,在运行第一个正则表达式(从我最初的帖子中,创建了
标记)之后,我运行:
r=re.compile(r'(*? \n(?!\s*)),re.DOTALL)
r、 sub(“\\1
”,带标签的字符串)
这将找到标记的第一个匹配项和\n
组合的最后一个匹配项,后面不是标记(基本上是指整个列表),并添加
标记
编辑:
我稍微修改了正则表达式,这样它就不会贪婪了。这样,它可以处理同一文档中的多个列表。唯一的要求是列表项之间没有空格,如下面提到的@Aprillion
编辑2:
修改了负前瞻,以处理列表项之间的空格,因此涵盖了所有情况只需逐行遍历文档,并检查正则表达式。无论何时成功匹配,请启动一个新的,无论何时停止匹配,请输入一个。谢谢您的回答。由于我对文档执行了一系列不同的正则表达式替换,因此我更愿意在这种情况下使用正则表达式。然而,如果我找不到,这可能就是解决方案。为什么不使用dom解析器呢?@Paranaix因为重新发明轮子太有趣了。我们从html解析文本,问题是如何将文本格式化为html。除非BeautifulSoup有一些我不知道的特性,否则页面会说:“BeautifulSoup是一个Python库,用于从HTML和XML文件中提取数据”。所以,只要它不做相反的事情(从非树结构文档中提取数据),这对我有什么帮助?另外,如果可能的话,我宁愿避免仅仅为了这个任务而使用另一个库。我不确定你所说的“欺骗”是什么意思?我认为您可能使用了一个糟糕的翻译器/翻译。BeautifulSoup是一个DOM操纵器。您可以使用它构建dom。他可以用它来解析文本。例如,在每一行中,他都会向文档中添加文本。。。如果他遇到
*
,他会添加一个ul
,然后添加li
,直到他遇到一个不以*
开头的新行,并且使用dom他可以从ul
中弹出。。。等等。你也不想用正则表达式来解决这个问题:谢谢。实际上,文档中可能有许多列表。正如我回答的@Guy Adini,除非我找到一个正则表达式来完成这个任务,否则我可能会使用这个解决方案。@user1102018不客气。我还通过修改打印行更新了我的答案,该行之前无意中将*
保留在生成的逐项列表中
str(document)
document.prettify()
r = re.compile(r'(<li>.*?</li>\n(?!\s*<li>))', re.DOTALL)
r.sub('<ul>\\1</ul>', string_with_li_tags)