2009-12-09 2 views
12

str.format()은 Python 2.6 및 Python 3에서 문자열 서식을 지정하기위한 새로운 표준입니다. str.format() 정규 표현식을 사용할 때 문제가 발생했습니다.Python 2.6+ str.format() 및 정규식

내가 지정된 도메인 아래에 하나의 수준있는 모든 도메인 또는 2 수준 아래 WWW 경우 지정된 도메인 아래의 2 개 수준이다 어떤 도메인을 반환하는 정규 표현식을 작성했습니다

...

지정된 도메인이 delivery.com이라고 가정하면 정규식은 a.delivery.com, b.delivery.com, www.cdelivery.com을 반환해야하지만 xadelivery.com을 반환하면 안됩니다. 결과를 제공해야이 실행

import re 

str1 = "www.pizza.delivery.com" 
str2 = "w.pizza.delivery.com" 
str3 = "pizza.delivery.com" 

if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}delivery.com$', str1): print 'String 1 matches!' 
if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}delivery.com$', str2): print 'String 2 matches!' 
if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}delivery.com$', str3): print 'String 3 matches!' 

: 나는 동적으로 str.format를 사용하여 delivery.com을 교체 할 때

String 1 matches! 
String 3 matches! 

지금, 문제가를 ...

if (re.match('^(w{3}\.)?([0-9A-Za-z-]+\.){1}{domainName}$'.format(domainName = 'delivery.com'), str1): print 'String 1 matches!' 

이를 str.format(){3}{1}이 함수의 매개 변수가 될 것으로 예상하기 때문에 실패 할 것으로 보입니다.

내가 + 연산자 문제는 아래에 제공

'^(w{3}\.)?([0-9A-Za-z-]+\.){1}' + domainName + '$' 

를 사용하여 문자열을 연결할 수있다 (내가 있으리라 믿고있어), 문자열 (일반적으로 정규식) {N} '가있을 때 가능 str.format()을 사용하는 것입니다 "안에 있습니까?

+0

질문에 직접 관련이 없지만 나중에 정규식에서 항상 원시 문자열을 사용하는 습관을 갖게되면 많은 슬픔을 피할 수 있습니다. –

+0

@Mark이 이유는 무엇입니까? 팁 고마워. – brildum

+4

일반적으로 문자열 리터럴에 백 슬래시를 넣을 때는 언제나 원시 문자열을 사용해야합니다. 그렇지 않으면 예기치 않은 문자열 이스케이프가 발생할 수 있습니다. 이것은 (비 - 원시) "c : \ names \ bob"이 당신이 생각하는 것을 의미하지는 않는 Windows 파일 경로에서 가장 분명합니다. 정규식에서 원시 문자열을 사용한다는 것은 정규식 문자열이 사용자가 입력하는 문자열이라는 것을 의미합니다. 정규식에서 하나의 백 슬래시를 매치 시키려면 다른 문자로 이스케이프 처리해야합니다. \\ 그러나 원시가 아닌 문자열의 시퀀스는 단일 백 슬래시를 생성하지만 정규식을 보면 분명하지 않습니다. 원시 문자열에서 r '\\'는 예상대로 전달됩니다. –

답변

20

먼저 문자열을 포맷 한 다음 regex를 사용해야합니다. 모든 것을 한 줄에 넣는 것은 실제로 가치가 없습니다. 이스케이프는 중괄호 배에 의해 수행됩니다

>>> pat= '^(w{{3}}\.)?([0-9A-Za-z-]+\.){{1}}{domainName}$'.format(domainName = 'delivery.com') 
>>> pat 
'^(w{3}\\.)?([0-9A-Za-z-]+\\.){1}delivery.com$' 
>>> re.match(pat, str1) 

또한, re.match 문자열의 시작 부분에 일치되어, 당신은 당신이 re.match를 사용하는 경우가 re.search를 사용하는 경우, 당신은 ^ 필요 ^를 넣을 필요가 없습니다 그러나.

정규식의 {1}은 다소 중복됨을 유의하십시오. the documentation

+4

'{1}'은 중복 될뿐만 아니라'www {'{3}}보다 명확하지 않습니다.원래의 일반적인 질문에 대답하지 않지만이 경우 더 나은 해결책 인 것 같습니다. –

7

, 당신이 서식 opertation 살아남을 원래 문자열에 {{}}를 사용하는 리터럴 { 또는 }이 필요합니다.

'^(w{{3}}\.)?([0-9A-Za-z-]+\.){{1}}{domainName}$'.format(domainName = 'delivery.com') 
관련 문제