搜索与替换:将方括号转换为XML标签
我会尽量简短明了。
给定以下内容
#!/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]
,需要再转换一次。我该怎么做才能最好地完成这个任务呢?
需要注意的事项
我的输入文本的作者并不总是一致。因此,最好开发一个宽松的正则表达式来找到 [b] WORD [/b] 或者作者写错的情况,比如 [b[WORD[/b]。我现在的想法是匹配类似 [b 或 b] 的内容。
我现在是逐行处理输入文件的,已经去掉了空行。我应该考虑在之后再处理这些吗?我没有明确的目标,但觉得可以在一次循环中完成。
这需要和 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 <strong>long</strong> text string</p></root>'
反向操作的结果同样不理想
>>> p.text
'this is a [b]long[/b] text string
>>> render_bbcode(etree.tostring(root))
u'<root><p>this is a <strong>long</strong> string</p></root>'
1 个回答
postmarkup这个库看起来最接近你想要做的事情。
http://pypi.python.org/pypi/postmarkup/1.1.4
不过,最近这个库的更新不多,但我也没看到其他更好的库。
从这个库开始,然后修改里面的内容来适应你的需求,可能比从头开始自己写解析器要快得多。
如果这个方向不合适,你可以考虑更底层的语法分析和解析,但这样会变得很复杂,可能还不如用简单的正则表达式和手动修正来得好。你的数据量有多大呢?
最后要提到的是,像这样的任务正是sed
这个工具的强项。如果你愿意花时间学习它,它会非常强大。不过,如果你对它不太熟悉,使用Python可能会更简单。