python - 使用 pyparsing 从具有特殊字符的字符串中解析列表

标签 python pyparsing

我想从可能包含特殊字符(例如\\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) 的便捷快捷方式,但是您用于 exprWord(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/

相关文章:

python - Pandas - 制作一些标题行值

Python:重新格式化一组文本文件的简洁/优雅的方式?

python - 如何使用 ast.literal_eval 评估 f 个字符串

python - pyparsing 和换行符

python - 将 Python 字符串或字典插入 MySQL

Python:读取png图像的默认/常用方法

python - 使用pyparsing解析配置文件

python - 如何逐行解析python代码直到表达式完成

python - 如何使用 pyparsing 构建完整的 C 解析器?

python - 使用 pyparsing 进行非贪婪列表解析