2009-12-09 20 views
12

str.format()'u kullanmak, Python 2.6 ve Python 3'teki dizeleri biçimlendirmek için yeni standarttır. Normal ifadelerle str.format()'u kullanırken bir sorunla karşılaşıyorum.Python 2.6+ str.format() ve normal ifadeler

Ben belirli bir etki altında tek seviyeli olan tüm alanları veya 2. düzey aşağıda www ise belirtilen alanın altında 2 düzeyleri, hiçbir etki dönmek için normal bir ifade yazdım

...

Belirtilen alanın delivery.com olduğunu varsayarsak, regex a.delivery.com, b.delivery.com, www.c.delivery.com adresini döndürmelidir, ancak xadelivery.com'u döndürmemelidir. sonuç vermelidir bu Running

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!' 

: Dinamik str.format kullanarak delivery.com değiştirmeye çalıştığınızda

String 1 matches! 
String 3 matches! 

Şimdi sorun şu ...

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

Bu başarısız gibi görünüyor, çünkü str.format(), {3} ve {1} işlevinin parametreler olmasını bekliyor.

I + operatöre soru Başına gelenleri

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

kullanarak dizeyi bitiştirmek olabilir (I varsayarak), dize (genellikle regex) {n} "olduğunda mümkün str.format() kullanmaktır "içinde mi?

+0

Soruyla doğrudan ilgili olmayan, ancak normal ifadenizde her zaman ham dizeleri kullanma alışkanlığına giderek kendinizi çok fazla kederden koruyacaksınız. –

+0

@Mark bunun nedenleri nelerdir? Bahşiş için teşekkürler. – brildum

+4

Kural olarak, herhangi bir zamanda dize değişmezlerine ters eğik çizgi koyduğunuzda, ham dizeleri kullanmalısınız. Aksi takdirde, beklenmedik dize çıkışları ile sonuçlanabilir. Bu, (ham olmayan) "c: \ names \ bob" ifadesinin sizin için ne anlama geldiğini kastetmediği Windows dosya yollarında en belirgindir. Bir normal ifadede, ham bir dize kullanmak, regex dizginiz yazdıklarınızdır. Tek bir ters eğik çizgiyi bir normal ifadeyle eşleştirmek için, bir diğeriyle kaçmanız gerekir: \\ Ancak, ham olmayan bir dizede bu dizi tek bir ters eğik çizgi oluşturur, ancak normal ifadenize bakmaktan belli değildir. Ham bir dizgede, r '\\' iniz beklendiği gibi gelir. –

cevap

20

İlk önce dizeyi biçimlendirmeniz ve sonra normal ifadeyi kullanmanız gerekir. Her şeyi tek bir sıraya koymak gerçekten buna değmez. Kaçış küme parantezi iki katına yapılır:

>>> 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) 

Ayrıca re.match dizesinin başında eşleşen edilir, size re.match kullanırsanız re.search kullanıyorsanız, size ^ ihtiyaç ^ koymak gerekmez , ancak.

Düzenli olarak {1} numaralı ifadenin gereksiz olduğunu unutmayın. the documentation Başına

+4

Sadece {1} 'gereksiz değil, w '{{3}}' den daha açık değil.Orijinal genel soruya cevap vermediğini biliyorum, ancak bu dava için daha iyi bir çözüm gibi görünüyor. –

7

, sen biçimlendirme opertation hayatta orijinal dizesinde {{ ve }} kullanmak için bir edebi { ya } gerekiyorsa.

'^(w{{3}}\.)?([0-9A-Za-z-]+\.){{1}}{domainName}$'.format(domainName = 'delivery.com') 
İlgili konular