2013-03-18 5 views
1

다음 입력과 일치시키고 싶습니다. 여러 줄을 사용하지 않고 특정 횟수만큼 그룹을 일치 시키려면 어떻게해야합니까? (^ (\ d +) (. +) $) {3}) (하지만 작동하지 않습니다.정규식 : 정확히 3 줄 일치

sample_string = """Breakpoint 12 reached 
     90 good morning 
    91 this is cool 
    92 this is bananas 
    """ 
pattern_for_continue = re.compile("""Breakpoint \s (\d+) \s reached \s (.+)$ 
           ^(\d+)\s+ (.+)\n 
           ^(\d+)\s+ (.+)\n 
           ^(\d+)\s+ (.+)\n 
            """, re.M|re.VERBOSE) 
matchobj = pattern_for_continue.match(sample_string) 
    print matchobj.group(0) 
+2

'$'를 (를) '\ n'(으)로 변경하십시오. – hughdbrown

+0

VERBOSE를 사용하면 * all * 공백이 일치하지 않으므로 첫 줄의 숫자 주위의 공백도 무시됩니다. –

+0

또한 여러 줄의 정규 표현식에서 공백은 정규식의 일부가 아니며 comemnts로 처리됩니다.명시 적으로'\ s +'와'\ s *'를 삽입해야합니다. – hughdbrown

답변

3

표현식 및 샘플 문제의 시리즈가 있습니다

  • VERBOSE의 사용은 모든 공간이 일치하지하게, 그래서 당신의 공간 첫 줄의 숫자 주변도 무시됩니다. 공백을 \s 또는 [ ]으로 바꿉니다 (후자는 리터럴 공백에만 해당하며 전자는 줄 바꿈 및 탭에도 일치 함).

  • 입력 샘플은 각 줄의 숫자 앞에 공백이 있지만 예제 패턴에서는 줄의 시작 부분에 숫자가 있어야합니다. 그 공백을 허용하거나 샘플 입력을 수정하십시오.

  • 가장 큰 문제는 반복 그룹 (결국 {3} 인 큰 그룹에 속한 (\d+) 내부)의 캡처 그룹이 마지막으로 일치하는 것을 캡처한다는 것입니다. 이전에 일치하는 두 줄이 아닌 92this is bananas이 표시됩니다. 모든 것을 극복하기 위해

, 명시 적으로 세 줄을 위해 그 패턴을 반복이 .

linepattern = r'[ ]* (\d+) [ ]+ ([^\n]+)\n' 

pattern_for_continue = re.compile(r""" 
    Breakpoint [ ]+ (\d+) [ ]+ reached [ ]+ ([^\n]*?)\n 
    {} 
""".format(linepattern * 3), re.MULTILINE|re.VERBOSE) 

어느, 샘플 입력, 반환 : 당신은 그 반복을 구현하기 위해 파이썬을 사용할 수

>>> pattern_for_continue.match(sample_string).groups() 
('12', '', '90', 'hey this is a great line', '91', 'this is cool too', '92', 'this is bananas') 

당신이 정말로 3 여분의 줄에있는 숫자 전에 공간과 일치하지 않는 경우

, 첫 번째 [ ]* 패턴을 linepattern에서 삭제할 수 있습니다.

+0

감사합니다. 내 질문을 업데이트했습니다. –

+1

@Rose :'input2'는 끝에 개행이 없습니다. 각 라인 *은 일치시킬 패턴을위한 개행을 가져야합니다. –

+0

완벽. 감사! –

1

코드

당신은 더 이런 일이 필요합니다

import re 

sample_string = """Breakpoint 12 reached 
90 hey this is a great line 
91 this is cool too 
92 this is bananas 
""" 
pattern_for_continue = re.compile(r""" 
    Breakpoint\s+(\d+)\s+reached\s+\n 
    (\d+) ([^\n]+?)\n 
    (\d+) ([^\n]+?)\n 
    (\d+) ([^\n]+?)\n 
""", re.MULTILINE|re.VERBOSE) 
matchobj = pattern_for_continue.match(sample_string) 

for i in range(1, 8): 
    print i, matchobj.group(i) 
print "Entire match:" 
print matchobj.group(0) 

결과를

1 12 
2 90 
3 hey this is a great line 
4 91 
5 this is cool too 
6 92 
7 this is bananas 
Entire match: 
0 Breakpoint 12 reached 
90 hey this is a great line 
91 this is cool too 
92 this is bananas 

이유

  • re.VERBOSE는 정규 표현식에서 공백을 명시 적으로 만듭니다. 필자는 데이터를 여러 줄 문자열로 왼쪽 정렬하여 부분적으로 수정했습니다. 아마도 이것이 실제 코드에서는 존재하지 않기 때문에 이것이 정당화된다고 생각합니다. 다중 행 문자열로 편집하는 것의 유물 일 수 있습니다.

  • $\n으로 바꿔야합니다.

  • 당신은 필요가 아닌 욕심 일치

+0

이것은 'sample_string'과 일치 할 수도 있지만 OP 'sample_string'과 일치하지 않습니다 –

+0

OP의 샘플 문자열 인 yes를 수정했습니다. 그것은 들여 쓰기가있는 "" "..." ""안에 넣은 잘라 붙여 넣기 코드이므로 실제 데이터는 그렇게 보이지 않습니다. – hughdbrown