【问题标题】:search and replace: convert square brackets to xml tags搜索和替换:将方括号转换为 xml 标签
【发布时间】:2011-06-21 23:51:35
【问题描述】:

我会尽量保持简明扼要。

鉴于以下

#!/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。文档的结构是相当静态的。因此,这并不像听起来那么疯狂。我目前把它分成几行。这是相关的,因为当我遍历每一行时,我可以轻松识别&lt;sect&gt;&lt;title&gt;,但通常&lt;para&gt; 在其行中会有一些额外的格式。在此示例中,[b] 需要再次转换。实现这一目标的最佳方法是什么?

注意事项

  1. 我的输入文本的作者并不总是一致的。因此,最好开发一个丢失的正则表达式来查找 [b] WORD [/b] 或当作者出现类似 [b[WORD[/b] 的错误时。我目前的想法是匹配 [b or 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;'

【问题讨论】:

  • 注意,我的另一个问题仍然有效。 stackoverflow.com/questions/6417881/…我还没有在我们的开发服务器上成功安装lxml,我正在本地机器上编码。
  • 您可能会尝试搜索 \[(.+?)\],然后找到匹配的 \[\1\] 结束标签,但您可能还需要考虑嵌套标签,取决于文本的复杂程度。
  • 此级别不会有嵌套标签。标签内应始终有一个字母,标签周围只有一两个单词。去年手工做了几百次之后,我观察到的最大作者错误是 [b[some word[b].括号方向错误和/或未正确闭合。
  • 如果您实际上是在解析 BBCode,您是否检查了现有的解析器以确保它们没有做您想做的事情?
  • 没有。出于某种原因,我没有想到。多么简单的建议,我怎么没想到呢?在我开始搜索 Ernst 之前,您能推荐一个吗?

标签: python xml regex lxml text-processing


【解决方案1】:

邮戳库似乎最接近您想要做的。

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

不幸的是,它最近没有得到很大的发展,但我没有看到任何其他看起来更好的库。

从那里开始并修改现有元素以适应您的语法可能比从头开始重新发明解析轮更快。

如果这不是一个好的方向,您可能会查看更底层的语法词法分析和解析,但这会很快变得复杂到您可能会更好地使用简单的重复正则表达式和手动更正。你的语料库有多大?

最后要注意的是,像这样的任务正是 sed 的编写目的。如果您愿意学习如何使用它,它可能会非常强大。但是,如果您对它还不满意,Python 可能会更容易。

【讨论】:

  • 嗨,保罗,感谢您提出问题。我精通 sed,但希望有一种“简单”的方法可以在 python 内部实现这一点。我在这个项目上花费了过多的时间,但我的项目总是鼓励学习。明天早上我会更深入地研究一下,然后告诉你进展如何。
  • 好的,经过快速测试,这将不起作用。我将修改我最初的问题以说明我对 postmark-1.1.4 的问题
  • 您可以考虑将邮戳的结果包装在 XML 中的 CDATA 元素中。它不会特别漂亮,但可以让你输入所写的元素。完成后,您希望字符串是正确的 XML,包括内部标签吗?为什么不在邮戳处理后让 lxml 解析字符串?您不必直接分配给那里的文本元素。
  • 在任何一种情况下,邮戳实际上都适合你,你只需要弄清楚你想让 lxml 做什么。
  • 我早上再看一遍。我确实希望字符串是正确的 xml,因为脚本将输出一个新的 xml 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-15
  • 2011-02-12
  • 2018-09-15
  • 2015-09-04
相关资源
最近更新 更多