2010-04-13 4 views
6

저는 Perl과 Ruby에 익숙하지만 파이썬에 익숙하지 않으므로 다음 작업을 수행 할 Python 방식을 누군가에게 보여줄 수 있기를 바랍니다. 여러 정규식에 대해 여러 줄을 비교하고 일치하는 그룹을 검색하려고합니다. 루비에서는이 같은 것입니다 : 일치하는 그룹이 정규 표현식에/검색어에 대한 일치하는 호출에서 반환 파이썬은 조건문에는 할당이 없거나 때문에 파이썬에서파이썬과 여러 정규식을 비교 문자열

# Revised to show variance in regex and related action. 
data, foo, bar = [], nil, nil 
input_lines.each do |line| 
    if line =~ /Foo(\d+)/ 
    foo = $1.to_i 
    elsif line =~ /Bar=(.*)$/ 
    bar = $1 
    elsif bar 
    data.push(line.to_f) 
    end 
end 

내 시도는 꽤 추한 밖으로 돌리고있다 switch 문. 이 문제에 관해서 파이썬 적 방법 (또는 생각하는 것)은 무엇입니까? 이 같은

+1

http://stackoverflow.com/questions/2554185/match-groups-in-python을 참조하십시오. – PaulMcG

+0

예, 그 질문은 제가 찾고있는 것입니다 - 감사합니다! – maerics

답변

1

뭔가하지만 예뻐 :

regexs = [re.compile('...'), ...] 

for regex in regexes: 
    m = regex.match(s) 
    if m: 
    print m.groups() 
    break 
else: 
    print 'No match' 
+1

나는 비슷한 것을 시도했지만 어떤 정규 표현식이 일치하는지에 따라 다른 행동을 취하고 싶다. 그래서 일치 목록이 발견되면 lambdas에 정규 표현식을 매핑하는 사전 목록으로 옮겼다.하지만 혼란스러운 코드를 만든다. – maerics

1

예 : "지정 및 테스트"에 대한 나의 오래된 recipe으로 파이썬에서 "즉석에서 이름을 바인딩"여러 가지 방법이 있습니다; 이 경우 아마 뭔가처럼 (파이썬의 이전 버전으로 작업하는 경우 약간의 변경이 필요 파이썬 2.6 가정) 같은 또 다른 방법을 선택할 것 :

import re 
pats_marks = (r'^A:(.*)$', 'FOO'), (r'^B:(.*)$', 'BAR') 
for line in lines: 
    mo, m = next(((mo, m) for p, m in pats_mark for mo in [re.match(p, line)] if mo), 
       (None, None)) 
    if mo: print '%s: %s' % (m, mo.group(1)) 
    else: print 'NO MATCH: %s' % line 

많은 사소한 세부 사항을 조정할 수 있습니다, 물론 일치하는 그룹으로 (.*?)이 아닌 (.*)을 선택했습니다. 즉, 바로 뒤에 오는 $을 사용하여 동일한 결과를 얻었으므로 짧은 양식을 선택했습니다 ;-) - RE를 사전 처리 컴파일하고 다르게 팩터링 할 수 있습니다 pats_mark 튜플 (예 : RE 패턴으로 색인 된 사전이있는 경우) 등

하지만 실질적인 아이디어는 ructure 데이터 기반이며 일치 항목을 하위 표현식 for mo in [re.match(p, line)]과 함께 즉시 바인딩 할 수 있습니다. 단일 항목 목록에 대한 "루프"(genexps는 루프가 아닌 할당에 의한 이름 만 바인드합니다. 일부는이 부분의 사용을 고려합니다. genexps '사양의 "까다로운",하지만 난 그것을 완벽하게 용납 할 수있는 파이썬 관용구, esp로 간주합니다. 이었기 때문에 어떤 의미에서 listcomps, genexps 'ancestors'가 설계되었을 때 고려되었습니다.

-1

정규 표현식은 세 번째 문자 이후의 문자를 단순히 사용합니다. , 경기를 수행하는 일치 그룹을 저장하고, 성공을위한 부울을 반환하는 중간 클래스 REMatcher를 사용

for line in open("file"): 
    if line.startswith("A:"): 
     print "FOO #{"+line[2:]+"}" 
    elif line.startswith("B:"): 
     print "BAR #{"+line[2:]+"}" 
    else: 
     print "No match" 
+0

좋은 방법이지만 분할 및 비교를 사용하십시오. 시작, 나머지 = line.split (':', 1) 시작하는 경우 == "A": 등 ... – moshez

+0

좋은데, 좀 더 일반적인 것을 찾고, 간단한 정규 표현식은 단지 설명을위한 것일뿐 실제 정규 표현식은 상당히 복잡합니다. – maerics