2014-09-03 2 views
3

전화 번호와 일치하는 정규 표현식을 작성했습니다. 내가 만난 문제 중 하나는 일부 우편 번호가 전화 번호처럼 보입니다. 예를 들어, 브라질, 우편 번호는 다음과 같습니다 :Python 정규식 부정적인 lookbehind가 일치하지 않음

In [63]: re.search(r"(?P<phone>\d+\.\d+-\d+)", "30.160-0131") 
Out[63]: <_sre.SRE_Match at 0x102150990> 

는 다행히 같은 우편 번호는 종종 일반적으로 "우편 번호를 의미 접두사와 함께 제공 :

30.160-0131 

그래서 간단한 정규식 그들에게 같은 잘못된 반응을 사로 잡을 것입니다 다음과 같이 ": 당신이 전화 번호처럼 보이는 뭔가 앞에 CEP를 참조하면

CEP 30.160-0131 

그래서, 다음은 전화 번호가 아니다 - 그것은 우편 번호입니다. 나는 negative lookbehind을 사용하여이를 포착하기 위해 정규 표현식을 작성하려고 시도했지만 작동하지 않습니다. 여전히 일치 함 :

In [62]: re.search(r"(?<!CEP)(\d+\.\d+-\d+)", "CEP 30.160-0131") 
Out[62]: <_sre.SRE_Match at 0x102150eb8> 

왜 여전히 일치합니까? 그리고 어떻게하면 부정적인 표정으로 경기에 실패 할 수 있습니까?

+1

일부가 일치 할 수 있기 때문에 : http://regex101.com/r/aU4fV4/1 – jonrsharpe

답변

1

:하지만 당신은 공백을 강제로, 또는 라인 앵커의 시작, 첫 번째 숫자 전에 잘 될 수 있습니다 :

m = re.search(r"CEP \d+\.\d+-\d+|(\d+\.\d+-\d+)", s) 

그리고 당신이 전화 번호에 대한 m.group(1)에 뭔가를 가지고있는 경우 다음 확인. re.findall


리틀 데모 :

>>> import re 
>>> s = "There is a CEP 30.160-0131 and a 30.160-0132 in that sentence, which repeats itself like there is a CEP 30.160-0131 and a 30.160-0132 in that sentence." 
>>> m = re.findall(r"CEP \d+\.\d+-\d+|(\d+\.\d+-\d+)", s) 
>>> print(m) 
['', '30.160-0132', '', '30.160-0132'] 

그리고 거기에서

, 당신은 빈 문자열을 필터링 할 수 있습니다.

+1

@misha 일반적으로 사용하는 코드에서 lookbehind에 액세스 할 수 없다면 도움이됩니다.) – Jerry

2

숫자를 고정하기 위해 아무 것도하지 않기 때문에 표현이 일치합니다. 예를 들어 : 즉시 CEP을 따르지 않기 때문에

"CEP 11.213-132" 

1.213-132 일치합니다. 당신은 전화 번호를 추출 여전히 당신이 그 우편 번호의 매칭을 허용하는 경우 부정적인 lookaheads를 방지 할 수 있습니다

re.search(r"(?<!CEP)(?:\s+|^)(\d+\.\d+-\d+)", s) 
+0

하지만 접두어가없는 경우와 일치하지 않습니다. 're.search (r "(? misha

+1

@misha, 맞아, 업데이트 된 표현식을 사용해보십시오 – perreal

+0

고마워요! 당신의 솔루션은 잘 작동했지만, @Jerry의 생각은 끝났다. 왜냐하면 이해하기가 더 쉽고 쉽기 때문이다. – misha

관련 문제