正则表达式:使用相同的开头捕获一组线?

时间:2012-05-08 00:09:17

标签: python regex

我正在编写一个脚本来浏览产品数据库,其中包含质量不佳,格式不一致的产品描述,以使其HTML统一。我遇到的一个问题是以相同的方式捕获和替换代码行。例如,我想替换他们所有的

• item 1
• item 2
• item 3

<ul>
  <li>item 1</li>
  <li>item 3</li>
  <li>item 2</li>
</ul>

&bull;行替换每个<li>content</li>行很容易,但我不能在我的生活中找出列表之前和之后的正则表达式。我的方法是捕获以&bull;开头的所有内容,直到有一个换行符&bull;开头。这是我最新的尝试(python):

In  : p = re.compile(
        r'&bull;.*(?!^&bull;)'
      )

In  : p.findall(text, re.MULTILINE, re.DOTALL)
Out : []

In  : p.findall(text, re.MULTILINE)
Out : ['&bull; item 1', '&bull; item 2', '&bull; item 3']

In  : p.findall(text, re.DOTALL)
Out : ['&bull; item 1', '&bull; item 2', '&bull; item 3']

In  : p.findall(text)
Out : ['&bull; item 1', '&bull; item 2', '&bull; item 3']

有关如何捕捉['&bull; item 1\n&bull; item 2\n&bull; item 3']等内容的任何想法?

3 个答案:

答案 0 :(得分:1)

首先必须将所有项目符号更改为<li>元素,然后在第二次执行时将其包含在<ul>元素中。

这是一个java示例。 Python也使用PCRE,所以它应该是相同的:

    String test = "&bull; item 1\r\n&bull; item 2\r\n&bull; item 3\r\n";
    test = test.replaceAll("&bull; (.*)(?!^&bull;)", "<li>$1</li>");
    System.out.println(test);
    test = test.replaceAll("(?s)(<li>.+</li>)+?", "<ul>\n$1\n</ul>");
    System.out.println(test);

输出:

<li>item 1</li>
<li>item 2</li>
<li>item 3</li>

<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>

答案 1 :(得分:1)

这是一个基于非正则表达式的解决方案:

with open('/tmp/example.txt') as f:
  lines_in = f.readlines()

inside_block = False
lines_out = []

for line in lines_in:
  if line.startswith('&bull; '):
    if not inside_block:
      lines_out.append('<ul>\n')
      inside_block = True
    lines_out.append('<li>{}</li>\n'.format(line.strip().replace('&bull; ','')))
  else:
    if inside_block:
      lines_out.append('</ul>\n')
      inside_block = False
    lines_out.append(line)

print ''.join(lines_in)
print '-'*78
print ''.join(lines_out)

试运行:

[~/Desktop]
|7>run /tmp/spam.py
spam
&bull; item 1
&bull; item 2
&bull; item 3
and eggs

------------------------------------------------------------------------------
spam
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
and eggs

答案 2 :(得分:0)

将内容读入字符串并拆分为“&amp; bull;”。迭代添加“&lt; li&gt;”的元素和“&lt; \ li&gt;”分别在每个元素之前和之后。