Pyparsing:嵌套Markdown重点

时间:2014-09-11 06:29:35

标签: python pyparsing

我正在使用一些简单的Markdown文本进行游戏,并学习一般的Pyparsing和语法。我几乎立即遇到了一个问题,我无法解决问题。我正在尝试解析CommonMark规范的简单版本以强调。在此设置中,允许嵌套强调,以便

*foo *bar* baz*

应该给:

<em>foo <em>bar</em> baz</em>

我已经尝试使用递归定义来匹配它,但它不起作用。这是一些示例代码:

from pyparsing import *

text = Word(printables,excludeChars="*")
enclosed = Forward()
emphasis = QuotedString("*").setParseAction(lambda x: "<em>%s</em>" % x[0],contents=enclosed)
enclosed << emphasis | text

test = """
*foo *bar* bar*
"""

print emphasis.transformString(test)

但我从中得到的是:

<em>foo </em>bar<em> bar</em>

原谅我的无聊;有人能指出我正确的方向吗?

修改

为了回应abarnert的重大调查问题,我将提供澄清。我只是在玩,所以我可以使用任意限制形式的符号。我假设只发生单个'*',并且它们不会彼此相邻。这使得空白消除歧义:*后面没有空格打开强调,*没有空格先关闭它。

即便如此,我也不确定如何继续进行Pyparsing。某种基于堆栈的方法,推送开放*并在验证结束时弹出它们?如何用Pyparsing做到这一点?还是有更有效的方法?

2 个答案:

答案 0 :(得分:2)

想想你要求的是什么。何时第二次*密切关注,何时开启嵌套强调?你没有写任何规则来区分它。由于它总是100%模棱两可,这意味着您可以获得的唯一可能结果是:

  • 不能强调关闭,或
  • 不能强调嵌套。

我怀疑你是否要求如何从第二个切换到第一个。

那么你要求的 是什么?

您需要实施某种规则来消除这两种可能性的歧义。

事实上,如果你阅读了你所链接的文档,他们就会有一套复杂的规则来准确定义*何时可以打开强调,什么时候可以打开强调,以及同样适用于闭关;鉴于这些规则,如果它仍然含糊不清,它会强调重点。你必须实现它。

答案 1 :(得分:2)

根据这些附加规则,我认为你根本不需要担心递归,只需处理开始和结束强调表达式,无论它们是否匹配:

from pyparsing import *

openEmphasis = (LineStart() | White()) + Suppress('*')
openEmphasis.setParseAction(lambda x: ''.join(x.asList()+['<em>']))
closeEmphasis = '*' + FollowedBy(White() | LineEnd())
closeEmphasis.setParseAction(lambda x: '</em>')

emphasis = (openEmphasis | closeEmphasis).leaveWhitespace()

test = """
*foo *bar* bar*
"""
print test
print emphasis.transformString(test)

打印:

*foo *bar* bar*

<em>foo <em>bar</em> bar</em>

您不是第一个通过这种应用程序旅行的人。当我在PyCon&#39; 06上展示时,一位热心的与会者潜入并解析了一些降价,输入字符串类似于"****a** b**** c**"或其他东西。我们对它进行了一些研究,但消除歧义的规则对于基本的pyparsing解析器来说只是上下文感知。