我需要解析一个包含 xml 注释的文件。具体来说,它是一个使用 MS ///
约定的 c# 文件。
从这里我需要拉出 foobar
,或者 ///foobar
也是可以接受的。 (注意 - 如果您将 xml 全部放在一行中,这仍然不起作用...)
testStr = """
///<summary>
/// foobar
///</summary>
"""
这是我的:
import pyparsing as pp
_eol = pp.Literal("\n").suppress()
_cPoundOpenXmlComment = Suppress('///<summary>') + pp.SkipTo(_eol)
_cPoundCloseXmlComment = Suppress('///</summary>') + pp.SkipTo(_eol)
_xmlCommentTxt = ~_cPoundCloseXmlComment + pp.SkipTo(_eol)
xmlComment = _cPoundOpenXmlComment + pp.OneOrMore(_xmlCommentTxt) + _cPoundCloseXmlComment
match = xmlComment.scanString(testStr)
并输出:
for item,start,stop in match:
for entry in item:
print(entry)
但我在跨多行工作的语法方面没有取得多大成功。
(注意 - 我在 python 3.2 中测试了上面的示例;它可以工作但是(根据我的问题)不打印任何值)
谢谢!
最佳答案
我认为 Literal('\n')
是你的问题。您不想构建带有空白字符的文字(因为默认情况下文字会在尝试匹配之前跳过空白)。尝试改用 LineEnd()
。
编辑 1:
仅仅因为您使用 LineEnd 获得无限循环并不意味着 Literal('\n') 更好。尝试在 _eol
定义的末尾添加 .setDebug()
,您会发现它永远不会匹配任何内容。
与其尝试将评论的主体定义为“一行或多行不是结束行,而是将所有内容都放到行尾”,不如这样做:
xmlComment = _cPoundOpenXmlComment + pp.SkipTo(_cPoundCloseXmlComment) + _cPoundCloseXmlComment
(您使用 LineEnd() 进行无限循环的原因是您实际上是在执行 OneOrMore(SkipTo(LineEnd())),但从不使用 LineEnd(),因此 OneOrMore 只是保持匹配、匹配和匹配,解析并返回一个空字符串,因为解析位置是在行尾。)
关于python - pyparsing - 解析 xml 注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7825030/