在pyparsing中处理转义字符

1 投票
1 回答
709 浏览
提问于 2025-04-18 03:20

我正在尝试用pyparsing写一个SGF解析器。解析器大部分已经完成了,但我搞不清楚Text这个标记。以下是我目前的代码:

import pyparsing as pp

Number = pp.Optional(pp.Literal("+") ^ pp.Literal("-")) \
             + pp.OneOrMore(pp.nums) 
Real   = Number + pp.Optional(pp.Literal(".") + pp.OneOrMore(pp.nums))
Double = pp.Literal("1") ^ pp.Literal("2")
Color  = pp.Literal("B") ^ pp.Literal("W")
Text   = """???"""
Stone  = Move = Point = pp.Word("abcdefghijklm", exact=2)

ValueType = pp.Empty() ^ Number ^ Real ^ Double ^ Color \
                ^ Text ^ Point ^ Move ^ Stone

Compose    = ValueType + pp.Literal(":") + ValueType
CValueType = ValueType ^ Compose

PropIdent = pp.Word(pp.alphas.upper(), min=1)
PropValue = pp.Literal("[") + CValueType + pp.Literal("]")
Property  = PropIdent + pp.OneOrMore(PropValue)

Node = pp.Literal(";") + pp.ZeroOrMore(Property)
Sequence  = pp.ZeroOrMore(Node)

GameTree = pp.Forward()
GameTree << pp.Literal("(") \
               + Sequence \
               + pp.ZeroOrMore(GameTree) \
            + pp.Literal(")")

Collection = pp.OneOrMore(GameTree)

这是在SGF规范中定义的Text标记:

Text是格式化的文本。除了换行符以外的空格都会被转换成空格(比如说,不允许有制表符、垂直制表符等)。

格式:软换行:在“\”后面的换行符(软换行会被转换成"",也就是被移除)。硬换行:任何其他遇到的换行符。

转义:“\”是转义字符。任何跟在“\”后面的字符都会原样插入(例外:空格仍然需要转换成空格!)。在Text中,以下字符需要转义:"]"、"\"和":"(只有在复合数据类型中使用时)。

问题出在转义部分,我搞不清楚该用什么语法或正则表达式来指定这个标记;看起来我应该定义“没有未转义的]\:的某些文本”,但我不知道该怎么做。

这里有一个例子:

C[emlroka [11k\] gg]

这是一个包含TextPropertyText部分是emlroka [11k\] gg

看起来pyparsing.QuotedString可以满足我的需求,但它需要有包围字符,比如",所以在我的问题中不适用。

谢谢你的时间。

1 个回答

0

我想我明白了。

Escape = Suppress(Literal("\\")) + Word("\\)]:", exact=1)
Text   = Combine(ZeroOrMore(Escape ^ Regex("[^\\]\\\\:]")))

可能还有一些特殊情况我没考虑到,但目前这个方法对我来说是有效的。

撰写回答