Python Regex - 识别列表中的第一个和最后一个项目

时间:2012-07-08 14:37:42

标签: 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

目前,我有这个:

r = re.compile(r'\*(.*)\n')
r.sub('<li>\1</li>', the_text_document)

创建没有< ul >标记的HTML列表 如何识别第一个和最后一个项目并用< ul >标签包围它们?

3 个答案:

答案 0 :(得分:1)

您可以逐行处理数据。下面这个快速而肮脏的解决方案可能会被整理,但对于您的数据,它可以解决问题。

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()

的产率:

some text in the document
<ul>
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
</ul>
some other text

根据您的数据的复杂程度,或者您是否重复编号列表等,这将需要修改,您可能希望寻找更通用的解决方案,或修改此启动代码以满足您的需求,只有您可以决定。< / p>

更新

编辑<li> .. </li>打印行以摆脱之前留下的*

答案 1 :(得分:1)

或使用BeautifulSoup

http://www.crummy.com/software/BeautifulSoup/bs4/doc/

修改

我显然必须给你一些如何阅读文档的提示。

  • 打开链接
  • 左边有一个大菜单(蓝绿色)
  • 如果仔细观察,您会注意到文档分为多个部分
    • 东西
    • 在树中导航
    • 搜索树
    • 修改树(得到它)
    • 输出(搞定了!)

还有更多的东西

  

Beautiful Soup是一个Python库,用于从HTML和XML文件中提取数据。它适用于您最喜欢的解析器,以提供导航,搜索和修改解析树的惯用方法。 它通常可以节省程序员数小时或数天的工作量。

在第一句话之后不要停止阅读......最后一句是非常重要的,中间是什么。

换句话说,你可以创建一个空文档......让我们说:

soup = BeautifulSoup("<div></div>")
document = soup.div

然后你阅读你文本的每一行..然后只要你有文字就这样做。

document.append(line)

如果该行以`*``

开头
ul = document.new_tag('ul')
document.append(ul)
document = ul

然后推送文档上的所有li ...一旦你最终阅读*,只需弹出父文件,然后文档返回到div。并继续这样做......你甚至可以递归地将ul插入到ul中。

解析完所有内容后......你可以做到

str(document)

document.prettify()

修改

刚才意识到你没有编辑html而是一个未格式化的文本..你可以尝试使用markdown。

http://daringfireball.net/projects/markdown/

答案 2 :(得分:1)

在玩了一些想法之后,我决定选择第二个正则表达式。 所以基本上,在运行第一个正则表达式(从我的原始帖子,创建<li>标签)后,我运行:

r = re.compile(r'(<li>.*?</li>\n(?!\s*<li>))', re.DOTALL)
r.sub('<ul>\\1</ul>', string_with_li_tags)

这会找到<li>标记的第一个匹配项和</li>\n组合的最后一个匹配项,后面跟不是<li>标记(实质上就是整个列表)并添加{{ 1}}标签。

编辑: 我修改了正则表达式,所以它不会贪婪。这样它就可以处理同一文档中的多个列表。唯一的要求是列表项之间没有空格,如下面提到的@Aprillion

编辑2: 修改了负前瞻以处理列表项之间的空格,因此涵盖了所有情况