2011-11-13 4 views
13

주어진 정규 표현식에 대해 문자열에서 모든 일치 항목을 찾아야합니다. 나는 그것이 내가 예상했던 것을하지 않는 경우를 발견 할 때까지 findall()을 사용했다. (A)의 모든 항목python - regex search and findall

findall() 일치 : 나는 (가장 긴 일치) 필요한 반환하지만 워드 프로세서는 동일해야 의미하지만 findall()가 다르게 동작 search()이 경우

regex = re.compile('(\d+,?)+') 
s = 'There are 9,000,000 bicycles in Beijing.' 

print re.search(regex, s).group(0) 
> 9,000,000 

print re.findall(regex, s) 
> ['000'] 

: 예를 들어, 패턴, 첫 번째뿐만 아니라 은 search()과 같습니다.

  • 왜 행동은 다른가요?

  • search()의 결과는 findall() (또는 다른 이름)으로 어떻게 얻을 수 있습니까?

+0

''([\ d,] +) ' – dawg

답변

15

좋아, 무슨 일인지 ... 워드 프로세서에서 볼 : 하나 개 이상의 그룹 패턴에 존재하는 경우

이 그룹의 목록을 반환; 패턴에 두 개 이상의 그룹이 있으면 튜플 목록이됩니다. 그것이 나오는 것에 따라

, 당신은 ... 그래서, 그것은 반환의 것이 마지막이 그룹의 발생, 또는 000

하나의 솔루션이다 "(\ D +,?)"그룹을해야합니까 다음이

regex = re.compile('((\d+,?)+)') 

같은 그룹에 의해 전체 정규식을 둘러싸도록, 그것은 [('9000000', '000'), 정합 기 모두를 포함하는 튜플이다를 리턴한다. 물론, 당신은 첫번째 것에 대해서만 신경을 씁니다.

편집 "이 나쁜 번호 9123입니다"와 같은

개인적으로, 나는 물건을 일치 방지하기 위해 다음과 같은 정규식

regex = re.compile('((\d+,)*\d+)') 

을 사용합니다.

여기에 괄호 표현을 둘러싸고 또는 튜플이있는 모든 경기에 액세스하는 데 사용할 수있는 반복자를 반환 finditer

s = "..." 
regex = re.compile('(\d+,?)+') 
it = re.finditer(regex, s) 

for match in it: 
    print match.group(0) 

처리하는 것을 방지 할 수있는 방법입니다. 이러한 일치 객체는 re.search가 반환하는 것과 동일하므로 group (0)은 예상 한 결과를 반환합니다.

+0

해 주셔서 감사합니다. 'finditer'는 당신이 제안한대로 실제로 더 잘 어울리는 것으로 나타났습니다. 정규식은 사용자 입력에서 나옵니다. 그래서 나는 그것을 제어 할 수 없습니다. – armandino

7

@ aleph_null의 answer은 문제의 원인을 정확하게 설명하지만 더 나은 해결책이 있다고 생각합니다.이 정규식을 사용

regex = re.compile(r'\d+(?:,\d+)*') 

더 나은 이유 몇 가지 이유 : 당신이 각 경기를 위해 하나 개의 결과를 얻을 수 있도록

  1. (?:...)이 비 캡처 그룹입니다.

  2. \d+(?:,\d+)*은 더 나은 정규 표현식으로, 더 효율적이고 오탐 (false positive)을 반환하지 않습니다.

  3. 가능하면 정규 표현식에는 항상 파이썬의 원시 문자열을 사용해야합니다. 정규 표현식 이스케이프 시퀀스 (예 : 의 경우 \b, 단어 경계)가 문자열 - 리터럴 이스케이프 시퀀스 (백 스페이스의 경우 \b)와 같이 해석 될 가능성이 적습니다.

+0

감사합니다. Alan! 전에 언급 했어야하지만 정규 표현식을 사용자 입력으로 제어 할 수는 없습니다. – armandino

+2

문제가 없습니다! 그러나 기록을 위해 사용자가 앱에서 실행하는 정규식을 입력하도록하는 것은 좋지 않은 아이디어입니다. 심하게 작성된 (또는 급하게 형식화 된) 정규 표현식이 시스템과 일치하지 않거나 시스템을 크래시하면 해당 사용자는 해당 사용자를 비난하게됩니다. ;) –