4

\ \ 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" with ' ' 理由は、文字通り文字を含むファイルから文字列を読み取ったため、\n, \rvar_nameまたはnumで解析できません(印刷できません)。

これは、ファイル内の(生の)文字列の例です。

LIST "one,two,
 three,
 \nfour,\rfive";

これについて何か提案はありますか?

4

1 に答える 1

2

あなたがここに示すように、Pyparsingは空白文字に対してかなり寛容であるため、これが問題であることに驚いています。

あなたが持っている1つの問題は、あなたの定義にありますlist_G

list_G = delimitedList(Word(printables))('mlist') #grammar for list

ここで何をしようとしているかはわかりますが、リスト要素の式には重要な問題があります。delimitedList(expr)は の便利なショートカットexpr + ZeroOrMore(Suppress(',') + expr)ですが、 に使用しているリスト要素式exprは でありWord(printables)、空白以外の文字の単語グループです。残念ながら、これにはリストの区切り文字「,」が含まれます。文字列「one,two,three」をこの式に渡す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 では、excludeCharsこれを簡素化するために Word に引数を追加しました。これで、次のように書くことができます:

word_of_everything_except_a_comma = Word(printables, excludeChars=',')

このような単語を使用すると、適切な 3 要素リストが得られます。

>>> 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']
于 2012-12-07T08:44:32.917 に答える