我正在尝试使用嵌套的花括号解析字符串数据,并且我想从解析的字符串元素中删除引号,也请从解析的列表中忽略","
,"+"
和空字符串""
。
这是我使用pyparsing
进行解析器定义的内容:
data = '{"url", {action1, action2}, "", class1 + class2}'
quotedString.setParseAction(removeQuotes)
parser = nestedExpr(opener="{", closer="}", ignoreExpr=(quotedString | Suppress(",") | Suppress("+")))
print(parser.parseString(data, parseAll=True)[0])
以下是输出:['url', ['action1', 'action2'], '', 'class1', 'class2']
我想在解析过程中以及在输出中忽略空字符串''
,我尝试在Suppress(",")
中添加ignoreExpr
,但似乎程序进入循环并给出警告SyntaxWarning: null string passed
而且,还有一种方法可以将Suppress()
字符串组合到一个列表中,而不是一个一个地写它们?
谢谢。
nestedExpr实际上只是一种“ cheater”表达式,用于轻松跳过括号,花括号等中的嵌套列表。要实际解析内容或对内容进行有意义的处理,定义一个实际的递归会更清楚表达式(尽管此[[is需要一些额外的工作)。
虽然我没有欺骗自己。我将word_sum
定义为带'+'分隔符的定界单词列表。这样可以消除“ +”号。然后,我再次对','分隔的部分再次使用了delimitedList,它又再次返回列表项的列表,并删除了定界','。使用这些快捷方式,递归语法最终看起来非常简短。请参阅下面带注释的代码中的注释。((关于列出多个字符来抑制多个字符的问题,您可以使用pyparsing oneOf:pp.Suppress(pp.oneOf('+ - , *'))
或pp.oneOf("+ - , *").suppress()
,以适合您的口味为准。
import pyparsing as pp
# delimitedList will suppress the delimiters, and just return the list elements
# delimitedList also will match just a single word
word = pp.Word(pp.alphas, pp.alphanums)
word_sum = pp.delimitedList(word, delim="+")
# expression for items that can be found inside the braces, in a list delimited by commas
# - define an explicit suppressor for ""
# - match QuotedStrings
# - match word_sums
item = pp.Literal('""').suppress() | pp.QuotedString('"') | word_sum
# define a Forward for the recursive expression
brace_expr = pp.Forward()
# define the contents of the recursive expression, which can include a reference to itself
# (use '<<=', not '=' for this definition)
LBRACE, RBRACE = map(pp.Suppress, "{}")
brace_expr <<=pp.Group(LBRACE + pp.delimitedList(item | brace_expr, delim=",") + RBRACE)
# try it out!
text = data = '{"url", {action1, action2}, "", class1 + class2}'
print(brace_expr.parseString(text)[0])
# prints
# ['url', ['action1', 'action2'], 'class1', 'class2']