2010-12-09 4 views
2

문자열 s이 더 크지 만 간단히하기 위해 단축했습니다.정규 표현식에서 일치하지 않는 선택적 문자열

작품 위의
>>> import re 
>>> s = "Blah. Tel.: 555 44 33 22." 
>>> m = re.search(r"\s*Tel\.:\s*(?P<telephone>.+?)\.", s) 
>>> m.group("telephone") 
'555 44 33 22' 

코드,하지만 난 그것을 선택하게 ()?에 정규식을 포장하면, 나는 어떤 전화를하지 않습니다.

>>> m = re.search(r"(\s*Tel\.:\s*(?P<telephone>.+?)\.)?", s) 
>>> m 
<_sre.SRE_Match object at 0x9369890> 
>>> m.group("telephone") 

무엇이 문제입니까? 감사!

편집 :

이 내가 큰 파일의 모든 라인에서 많은 값을 얻고있는 더 큰 정규 표현식의 일부입니다.

regex = r"^(?P<title>.[^(]+);" \ 
     "\s*(?P<subtitle>.+)\." \ 
     "\s*Tel\.:\s*(?P<telephone>.+?)(\.|;)" \ 
     "\s*(?P<url>(www\.|http://).+?\.[a-zA-Z]+)(\.|;)" \ 
     "(\s*(?P<text>.+?)\.)?" \ 
     "\s*coor:(\s*(?P<lat>.+?),\s*(?P<long>.+?))?$" 

하나 개의 샘플 라인 수 :

l = "Title title; Subtitle, subtitle. Tel.: 555 33 44 11. www.url.com. coor: 11.11111, -2.222222 

그리고 다른 샘플 라인 : 그것은 정말 큰 정규식

l = "Title2 title; Subtitle2, subtitle. Tel.: 555 33 44 11. www.url2.com. coor: 44.444444, -6.66666 

, 난 그것을 게시되지 않은 이유가 그래서.

답변

0

귀하의 정규식은 titlesubtitle 비트가 일치하는 것을 너무 불특정입니다. 그들은 전화 부분을 집어 삼키고, 그것이 선택 사항이된다면 정규 표현식의 다음 부분에서 계속됩니다 (성공합니다). 옵션이 아닌 경우에만 정규식 엔진이 역 추적하여 전체 일치를 찾을 수 있어야합니다.

regex = r"^(?P<title>[^;]+);" \ 
     "\s*(?P<subtitle>[^.]+)\." \ 
     "(\s*Tel\.:\s*(?P<telephone>.+?)(\.|;))?" \ 
     "\s*(?P<url>(www\.|http://).+?\.[a-zA-Z]+)(\.|;)" \ 
     "(\s*(?P<text>.+?)\.)?" \ 
     "\s*coor:(\s*(?P<lat>.+?),\s*(?P<long>.+?))?$" 
+0

너 어디 맞아! 도움을 주신 모든 분들께 감사드립니다. :) – Menda

2

(anything)?은 문자열 시작 부분 (Blah 이전)의 0 문자열과 일치하므로 더 이상 검색 할 필요가 없습니다.

편집 :

당신이 많은 라인을 가지고 오직 그들 중 일부는 원하는 문자열을 포함하는 경우, 다음을 시도해보십시오 : 빈 문자열이 정규 표현식에 대한 유효한 일치하기 때문에

import re 

rex = re.compile(r"\s*Tel\.:\s*(?P<telephone>.+?)\.") 
for line in lines: 
    m = rex.search(line) 
    if m: 
     print m.group("telephone") 
+1

의 시도/정신/신경/g –

+0

@ 팀, 감사, 정확하게! – eumiro

2

입니다 , 더 긴 성냥보다는 선호된다.

re.findall을 살펴볼 수 있습니다.

편집 : 당신은 모두 정규 표현식 밖으로 선택성을 이동할 수는 :

import re 
s = "Blah. Tel.: 555 44 33 22." 
m = re.search(r"\s*Tel\.:\s*(?P<telephone>.+?)\.", s) 
if m is not None: 
    print m.group("telephone") 
+0

감사합니다. 어떻게이 '게으른'동작을 피할 수 있습니까? – Menda

+0

're.findall'을 사용해보세요. 이것은 당신에게 모든 일치를 제공 할 것입니다 (비 었는지 아닌지). – NPE

+0

@Menda - 왜 이것을하고 싶습니까? 빈 경기가 많이 생길 것입니다. – eumiro

관련 문제