搜索与替换:将方括号转换为XML标签

1 投票
1 回答
1061 浏览
提问于 2025-04-16 20:02

我会尽量简短明了。

给定以下内容

#!/usr/bin/python
from lxml import etree

root = etree.Element('root')
sect = etree.SubElement(root,'sect')
para = etree.SubElement(sect,'para')
para.text = 'this is a [b]long[/b] block of text. Much longer than this example makes it out to be.'

我该如何将输出转换成我下面的样子。注意到 [b] 的部分变成了元素 <b>

<root> 
  <sect>
    <para>
       this is a <b>long</b> block of text. 
      Much longer than this example makes it out to be.
    </para>
  </sect>
</root>

我的实际输入和 XML 要复杂得多。不过,这就是大概意思。我把一个标准格式的文本文件转换成 XML。这个文档的结构相对固定。所以,这并不像听起来那么复杂。我现在已经把它分成了多行。这很重要,因为在处理每一行时,我能很容易识别出 <sect><title>,但有时候 <para> 的行里会有一些额外的格式,比如这个例子中的 [b],需要再转换一次。我该怎么做才能最好地完成这个任务呢?

需要注意的事项

  1. 我的输入文本的作者并不总是一致。因此,最好开发一个宽松的正则表达式来找到 [b] WORD [/b] 或者作者写错的情况,比如 [b[WORD[/b]。我现在的想法是匹配类似 [b 或 b] 的内容。

  2. 我现在是逐行处理输入文件的,已经去掉了空行。我应该考虑在之后再处理这些吗?我没有明确的目标,但觉得可以在一次循环中完成。

  3. 这需要和 lxml 兼容,以便我输出文档。例如,下面的编辑中有我对 bbc 解析器的评论。

我今天下午大部分时间都在处理这个问题,可以讨论我采取的更多方法。我会在晚上继续工作,如果有其他需要注意的事项,我会相应更新这个问题。

编辑:或者我在 bbc 解析器上的问题

Paul 贴心地建议了 postmarkup-1.1.4,但正如你所见,它和 lxml 的兼容性不好,转换元素时变成了实体。这是我今天下午在通过搜索和替换时遇到的问题。最终,这确实是一个完美的 sed 解决方案。正如有人指出的那样。不过,我希望自己不是这个脚本的最终用户,而是希望所有内容都能在一个命令中完成。

>>> p.text = render_bbcode(p.text)
>>> p.text
'this is a <strong>long</strong> text string'
>>> etree.tostring(root)
'<root><p>this is a &lt;strong&gt;long&lt;/strong&gt; text string</p></root>'

反向操作的结果同样不理想

 >>> p.text
 'this is a [b]long[/b] text string
 >>> render_bbcode(etree.tostring(root))
 u'&lt;root&gt;&lt;p&gt;this is a <strong>long</strong> string&lt;/p&gt;&lt;/root&gt;'

1 个回答

2

postmarkup这个库看起来最接近你想要做的事情。

http://pypi.python.org/pypi/postmarkup/1.1.4

不过,最近这个库的更新不多,但我也没看到其他更好的库。

从这个库开始,然后修改里面的内容来适应你的需求,可能比从头开始自己写解析器要快得多。

如果这个方向不合适,你可以考虑更底层的语法分析和解析,但这样会变得很复杂,可能还不如用简单的正则表达式和手动修正来得好。你的数据量有多大呢?

最后要提到的是,像这样的任务正是sed这个工具的强项。如果你愿意花时间学习它,它会非常强大。不过,如果你对它不太熟悉,使用Python可能会更简单。

撰写回答