我正在使用一些简单的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做到这一点?还是有更有效的方法?
答案 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解析器来说只是上下文感知。