2012-12-06 6 views
3

\\ 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의 ​​말씀 (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, \r이고 var_name 또는 num로 구문 분석 할 수 없습니다 (인쇄 할 수 없음)

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

당신이 이것에 대해 어떤 제안이 있습니까 : (210)

이 파일에서 (원시) 문자열의 예입니다?

+0

당신이 s''에서 일부 특수 문자를 포함하도록 질문을 편집 할 수, 그리고이 두 단계 방식으로 분석 할 경우 문제가 무엇인지 보여 ? – PaulMcG

+0

문자열 자체에 백 슬래시 문자와 'n'문자가 실제로있는 경우'unwanted = Word ('\\', 'rnt', exact = 2)와 같은 표현식을 정의한 다음'G .ignore (원치 않는)'. – PaulMcG

+0

멋진 해결책 인 것 같습니다. 파일을 읽은 후 파싱하기 바로 전에'\ t \ n \ r'을 공백으로 대체하는 현재의 해킹과 동등해야합니다. 감사합니다 –

답변

1

여기에 표시된 것처럼 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'] 

당신은 말할 방법이 필요합니다 "나는 단어가되고 싶어 쉼표가 아닌 모든 것을 인쇄 할 수 있습니다. " 대한 파싱의 이전 버전에서는이 같은 뭔가이 스스로해야 할 일을했을 : 버전 1.5.6에서

word_of_everything_except_a_comma = Word(''.join(c for c in printables if c != ',')) 

,이를 단순화하기 위해 말씀에 excludeChars 인수를 추가했습니다. 이제 당신은 그냥 쓸 수 있습니다 :

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'] 

이것은 당신이 어려움을 겪고 있던 문제가있을 수 있습니다를 예정대로 대한 파싱 암시 것이다 당신이 밖으로 제거하는 공백 문자 건너 뛰기 :

>>> s = "one, two\t\t,\n\n\t\t\t three" 
>>> print (s) 
one, two    , 

          three 
>>> print (list_G.parseString(s)) 
['one', 'two', 'three'] 
+0

안녕 폴, 변수 및 숫자에 대한 문법을 ​​사용했지만 청소기 때문에 포스트에'printables '를 사용하기로 결정했습니다 (편집 된 게시물 참조). 일이 제대로 작동하지 않을 때 예를 들어 본 글을 편집했습니다. 희망을 가져보십시오. –

관련 문제