我想从可能包含特殊字符(例如\\n\r\n\t)的字符串字段中解析一个列表,并扩展到多行。目前,我必须先解析字符串,清理它,然后在那个干净的字符串上应用列表语法。它工作正常,但只是想知道是否有更好的方法。
这是我目前拥有的
str_ = QuotedString('"',escChar='\\',multiline=True) #grammar for str
str_.setParseAction(lambda pr: pr[0].replace('\\n',' ')\
.replace('\\r', ' ')\
.replace('\r', ' ')\
.replace('\t', ' '))
list_G = delimitedList(Word(printables))('mlist') #grammar for list
def pa(st,locn,pr): return list_G.parseString(pr.mystr)
mylist = Group(str_('mystr').addParseAction(pa)) #read in the str then re-parse
G = Keyword("LIST") + mylist('thelist') + ';' #grammar for the whole thing
s = 'LIST "one,two,three" ;'
编辑: list_G 中的 Word(printables) 改为
var_grammar = Word(alphas+"_", alphanums + "_") #"_a,a2b_,.."
num_grammar = Regex(r"[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?")('num')
list_G = delimitedList(var_grammar|num_grammar)('mlist') #grammar for list
G = Keyword("LIST") + '"' + mylist('thelist') + '"' + ';'
迫使我进行上述清理工作,将 "\\n", "\\r"替换为 ' '
的原因是因为我从字面上包含的文件中读取了字符串字符 \n,\r
以及那些不能被 var_name 或 num 解析的字符(它们不可打印)
这是文件中(原始)字符串的示例:
LIST "one,two,
three,
\nfour,\rfive";
对此您有什么建议吗?
最佳答案
Pyparsing 非常容忍您在此处显示的空白字符,所以我很惊讶这是一个问题。
您确实遇到的一个问题是您对 list_G
的定义:
list_G = delimitedList(Word(printables))('mlist') #grammar for list
我明白你在这里想做什么,但你的列表元素表达式有一个关键问题。 delimitedList(expr)
是 expr + ZeroOrMore(Suppress(',') + expr)
的便捷快捷方式,但是您用于 expr
是 Word(printables)
,一个由任何非空白字符组成的词组。不幸的是,这包括 ',',您的列表分隔符。当您将字符串“一、二、三”传递给此表达式时,Word(printables)
将在查找分隔符之前解析整个内容:
>>> list_G = delimitedList(Word(printables))
>>> print (list_G.parseString("one,two,three"))
['one,two,three']
您需要一种方式来表达“我希望我的话是所有可打印的内容,而不是逗号”。在旧版本的 pyparsing 中,你必须自己用类似的东西来做这件事:
word_of_everything_except_a_comma = Word(''.join(c for c in printables if c != ','))
在 1.5.6 版中,我向 Word 添加了一个 excludeChars
参数以简化此操作。现在你可以写:
word_of_everything_except_a_comma = Word(printables, excludeChars=',')
用这样的词,你会得到一个合适的三元素列表:
>>> list_G = delimitedList(Word(printables, excludeChars=','))
>>> print (list_G.parseString("one,two,three"))
['one', 'two', 'three']
这可能是您遇到的问题,因为 pyparsing 将隐式跳过您要删除的空白字符:
>>> s = "one, two\t\t,\n\n\t\t\t three"
>>> print (s)
one, two ,
three
>>> print (list_G.parseString(s))
['one', 'two', 'three']
关于python - 使用 pyparsing 从具有特殊字符的字符串中解析列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13754007/