2011-04-14 2 views
4

나는 내가 파이썬에서이 파일을 읽을 수파이썬에서 정규식없이 문자열에 텍스트 형식을 일치시키는 방법은 무엇입니까?

[I,L,Ls,R,Rs,p,e,n] = textread(f1,'[ %u ] L= %u%s R= %u%s p= %n e=%u n=%u') 

에 의해 주어진이 파일을 읽을 수 Matlab code을 보았다

[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34 

예시 형태의 선으로 파일을 읽고있다. 내가 아는 유일한 것은의 정규식이며,이 라인도 일부를 읽는 못생긴

re.compile('\s*\[\s*(?P<id>\d+)\s*\]\s*L\s*=\s*(?P<Lint>\d+)\s*\((?P<Ltype>[DG])\)\s*R\s*=\s*(?P<Rint>\d+)\s*') 

같은 것을 리드! 파이썬에서 더 쉬운 방법이 있나요?

+1

다음을 시도하십시오. https://hkn.eecs.berkeley.edu/~dyoo/python/scanf/ –

+1

사실, 당신의 정규 표현식에 관해서 추악한 것은 그것이 주석이 많은 verbose 모드로 작성되지 않는다는 것입니다. 한 줄에 하나의 이름이 붙은 캡쳐 그룹으로 확장하면 그것은 아름답고 (정확하고 효율적이며 유지 보수가 가능하고 완전한 기능을하는) 것이 될 것입니다! – ridgerunner

+0

문제는 정규 표현식이 일부 입력에 바람직하지 않은 일을하도록 바인딩되어 있다는 것입니다. 특히 이상한 문자가 있고 명확한 표준이없는 경우 특히 그렇습니다. 나는 단지 내가 알고있는 것을 원한다. – sudo

답변

1

대한 파싱 읽을에서 대체입니다 깨지기 쉬운 regex 프로세서. 아래의 파서 예제는 명시된 형식과 다양한 추가 공백 및 할당 표현식의 임의 순서를 처리합니다. 정규 표현식에서 명명 된 그룹을 사용한 것처럼 pyparsing은 결과 이름을 지원하므로 dict 또는 속성 구문 (data [ 'Lint'] 또는 data.Lint)을 사용하여 구문 분석 된 데이터에 액세스 할 수 있습니다. 이후 값이 가능한 형태로 이미 수 있도록

from pyparsing import Suppress, Word, nums, oneOf, Regex, ZeroOrMore, Optional 

# define basic punctuation 
EQ,LPAR,RPAR,LBRACK,RBRACK = map(Suppress,"=()[]") 

# numeric values 
integer = Word(nums).setParseAction(lambda t : int(t[0])) 
real = Regex(r"[+-]?\d+\.\d*").setParseAction(lambda t : float(t[0])) 

# id and assignment fields 
idRef = LBRACK + integer("id") + RBRACK 
typesep = LPAR + oneOf("D G") + RPAR 
lExpr = 'L' + EQ + integer("Lint") 
rExpr = 'R' + EQ + integer("Rint") 
pExpr = 'p' + EQ + real("pFloat") 
eExpr = 'e' + EQ + integer("Eint") 
nExpr = 'n' + EQ + integer("Nint") 

# accept assignments in any order, with or without leading (D) or (G) 
assignment = lExpr | rExpr | pExpr | eExpr | nExpr 
line = idRef + lExpr + ZeroOrMore(Optional(typesep) + assignment) 


# test the parser 
text = "[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34" 
data = line.parseString(text) 
print data.dump() 


# prints 
# [0, 'L', 9, 'D', 'R', 14, 'D', 'p', 0.034722200000000002, 'e', 10, 'n', 34] 
# - Eint: 10 
# - Lint: 9 
# - Nint: 34 
# - Rint: 14 
# - id: 0 
# - pFloat: 0.0347222 

는 또한, 구문 분석 작업은, 구문 분석시에는 현악기> INT 또는 현악기와> 부동 소수점 변환을 수행. (구문 분석에서 이러한 식을 구문 분석하는 동안 숫자로 구성된 단어 (Word(nums))는 안전하게 int로 변환되므로 일치하는 문자열을 다시 가져 오는 대신 변환을 수행하는 것이 가장 좋습니다. 문자열의 순서를 다시 처리하고 정수, 부동 소수점 등을 검색하려고합니까?)

1

파이썬에는 scanf 등가물 as stated on the re page for Python이 없습니다.

파이썬에는 현재 scanf()와 동일한 기능이 없습니다. 일반 표현식은 일반적으로 scanf() 형식 문자열보다 강력하지만 더 자세한 정보입니다. 아래의 표는 scanf() 형식 토큰과 정규 표현식 사이에 다소간 동등한 매핑을 제공합니다.

그러나 아마도 해당 페이지의 매핑을 사용하여 자신의 scanf와 유사한 모듈을 만들 수 있습니다.

3

당신은 대체/탈출로를 구축하여 정규 표현식을 더 읽기 쉽게 만들 수 있습니다 ...

number = "([-+0-9.DdEe ]+)" 
unit = r"\(([^)]+)\)" 
t = "[X] L=XU R=XU p=X e=X n=X" 
m = re.compile(re.escape(t).replace("X", number).replace("U", unit)) 
+0

'% u'는'\ d +'로 대체되어야하고 **는 **'([- + 0-9.DdEe] +)가 아니며'% s'는'\ S +'로 대체 될 수 있습니다 [scanf ] (http://docs.python.org/library/re.html#simulating-scanf) – jfs

2

이 더 많거나 적은 파이썬 나에게 같습니다

line = "[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34" 

parts = (None, int, None, 
     None, int, str, 
     None, int, str, 
     None, float, 
     None, int, 
     None, int) 

[I,L,Ls,R,Rs,p,e,n] = [f(x) for f, x in zip(parts, line.split()) if f is not None] 

print [I,L,Ls,R,Rs,p,e,n] 
관련 문제