파이썬 정규식이 겹치는 모든 일치 항목을 찾으십니까?


101

파이썬 2.6에서 re를 사용하여 더 큰 일련의 숫자 내에서 모든 10 자리 일련의 숫자를 찾으려고합니다.

나는 쉽게 겹치는 경기를 잡을 수는 없지만 숫자 시리즈의 모든 경기를 원합니다. 예 :

"123456789123456789"에서

다음 목록을 받아야합니다.

[1234567891,2345678912,3456789123,4567891234,5678912345,6789123456,7891234567,8912345678,9123456789]

"예측"에 대한 참조를 찾았지만 내가 본 예에서는 더 큰 그룹이 아닌 숫자 쌍만 표시하고 두 자리 이상으로 변환 할 수 없습니다.


6
겹치는 일치가 같은 지점에서 시작하면 제시된 솔루션이 작동하지 않습니다. 예를 들어 "a | ab | abc"를 "abcd"와 일치 시키면 하나의 결과 만 반환됩니다. match ()를 여러 번 호출하고 '종료'경계를 수동으로 추적하지 않는 솔루션이 있습니까?
Vítor De Araújo

@ VítorDeAraújo : 중첩 된 정규식 (a|ab|abc)은 일반적으로 중첩 된 캡처 그룹이있는 중첩되지 않은 정규식 으로 다시 작성 될 수 있습니다. 예를 들어 (a(b(c)?)?)?일치를 풀 때 가장 바깥 쪽 (즉, 가장 왼쪽) 캡처 그룹을 제외한 모든 캡처 그룹을 무시합니다. 분명히 이것은 약간 고통스럽고 덜 읽기 쉽습니다. 이것은 또한 일치하는 더 성능이 좋은 정규식이 될 것입니다.
smci

답변:


179

미리보기 내에서 캡처 그룹을 사용합니다. 미리보기는 관심있는 텍스트를 캡처하지만 실제 일치는 기술적으로 미리보기 이전의 너비가 0 인 하위 문자열이므로 일치 항목이 기술적으로 겹치지 않습니다.

import re 
s = "123456789123456789"
matches = re.finditer(r'(?=(\d{10}))',s)
results = [int(match.group(1)) for match in matches]
# results: 
# [1234567891,
#  2345678912,
#  3456789123,
#  4567891234,
#  5678912345,
#  6789123456,
#  7891234567,
#  8912345678,
#  9123456789]

2
내 대답은 이것보다 적어도 2 배 빠릅니다. 하지만이 솔루션은 까다 롭습니다.
eyquem 2013

16
설명 = 패턴 (10 자리)을 검색하는 대신 패턴이 따르는 모든 항목을 검색합니다. 따라서 문자열의 위치 0, 문자열의 위치 1 등을 찾습니다. 그런 다음 일치하는 패턴 인 group (1)을 잡고 목록을 만듭니다. 아주 멋지다.
Tal Weiss

10
저는 StackOverflow에 가입하고 질문에 답했으며이 답변을 찬성 할 수 있도록 평판을 올렸습니다. 지금은 Python 2.4를 사용하고 있으므로 Python 3의 고급 정규식 함수를 사용할 수 없습니다. 이것은 제가 찾던 일종의 기괴한 속임수입니다.
TheSoundDefense

2
코드에 더 많은 설명을 추가 할 수 있습니까? 답변에 코드를 포함하는 것이 Stack Overflow에 따라 가장 좋은 방법은 아닙니다. 확실히 사람들을 도울 것입니다.
Akshay Hazari

1
이것은 정말 도움이됩니다. 감사합니다 : D
Sreekiran

80

겹치는 일치를 지원하는 타사 regex모듈 (아님 re)을 사용해 볼 수도 있습니다 .

>>> import regex as re
>>> s = "123456789123456789"
>>> matches = re.findall(r'\d{10}', s, overlapped=True)
>>> for match in matches: print(match)  # print match
...
1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

나는 얻는다 :TypeError: findall() got an unexpected keyword argument 'overlapped'
Carsten

@Carsten : 먼저 regex모듈 을 설치해야 합니다.pip install regex
David C

고마워요. 정규식이 설치되어 있지 않으면 가져 오기 오류가 발생할 것이라고 생각했을 것입니다
Carsten

17

나는 정규식을 좋아하지만 여기에서는 필요하지 않습니다.

간단히

s =  "123456789123456789"

n = 10
li = [ s[i:i+n] for i in xrange(len(s)-n+1) ]
print '\n'.join(li)

결과

1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

10
정규식은 "더 큰 일련의 숫자 내"에 대한 특별한 지식을 적용하기 때문에 여기서 만 필요하지 않으므로 모든 위치 0 <= i < len(s)-n+1가 10 자리 일치의 시작이 보장된다는 것을 이미 알고 있습니다. 또한 나는 당신의 코드가 빨라질 수 있다고 생각하고 속도를 위해 코드 골프에 흥미로울 것입니다.
smci
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.