2009-12-09 6 views
12

Sử dụng str.format() là chuẩn mới để định dạng chuỗi trong Python 2.6 và Python 3. Tôi đã gặp sự cố khi sử dụng str.format() với cụm từ thông dụng.Python 2.6+ str.format() và cụm từ thông dụng

Tôi đã viết một biểu thức chính quy để trả lại tất cả các lĩnh vực mà có một mức độ đơn dưới một miền cụ thể hoặc bất kỳ lĩnh vực mà 2 cấp độ bên dưới tên miền xác định, nếu mức độ 2 dưới đây là www ...

Giả sử tên miền được chỉ định là delivery.com, regex của tôi phải trả về a.delivery.com, b.delivery.com, www.c.delivery.com ... nhưng không nên trả lại 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!' 

Chạy điều này sẽ cho kết quả:

String 1 matches! 
String 3 matches! 

Bây giờ, vấn đề là khi tôi cố gắng để thay thế delivery.com động sử dụng str.format ...

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

này dường như không thành công, vì str.format() mong đợi các số {3}{1} là các tham số cho hàm. (Tôi giả sử)

tôi có thể nối chuỗi sử dụng + nhà điều hành

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

Câu hỏi đặt ra đi xuống đến, là nó có thể sử dụng str.format() khi chuỗi (thường regex) có "{n} "trong đó?

+0

Không liên quan trực tiếp đến câu hỏi, nhưng bạn sẽ tiết kiệm cho mình rất nhiều đau buồn sau này bằng cách sử dụng thói quen luôn sử dụng chuỗi thô trong regex của bạn. –

+0

@Mark lý do cho điều này là gì? Cảm ơn vì tiền hỗ trợ. – brildum

+4

Theo quy tắc, bất cứ khi nào bạn đặt dấu gạch chéo ngược trong chuỗi ký tự chuỗi, bạn nên sử dụng chuỗi thô. Nếu không, bạn có thể kết thúc với thoát chuỗi không mong muốn. Điều này là hiển nhiên nhất trong các đường dẫn tệp của Windows nơi (không phải thô) "c: \ names \ bob" không có nghĩa là bạn nghĩ nó có nghĩa là gì. Trong một regex, sử dụng một chuỗi thô có nghĩa là chuỗi regex của bạn là những gì bạn gõ. Để phù hợp với một dấu gạch chéo ngược duy nhất trong một regex, bạn cần phải thoát khỏi nó bằng cách khác: \\ Tuy nhiên, chuỗi trong một chuỗi không phải thô tạo ra một dấu gạch chéo ngược đơn nhưng không rõ ràng khi nhìn vào regex của bạn. Trong một chuỗi thô, r '\\' của bạn đi qua như mong đợi. –

Trả lời

20

trước tiên bạn cần phải định dạng chuỗi và sau đó sử dụng regex. Nó thực sự không có giá trị để đưa mọi thứ vào một dòng duy nhất. Thoát được thực hiện bằng cách nhân đôi dấu ngoặc nhọn:

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

Ngoài ra, re.match là phù hợp với lúc bắt đầu của chuỗi, bạn không cần phải đặt ^ nếu bạn sử dụng re.match, bạn cần ^ nếu bạn đang sử dụng re.search , Tuy nhiên.

Xin lưu ý rằng {1} trong regex khá dư thừa.

+4

Không chỉ là '{1}' dư thừa, nhưng sẽ không 'www' rõ ràng hơn' w {{3}} '.Tôi biết nó không trả lời câu hỏi chung ban đầu nhưng có vẻ như là một giải pháp tốt hơn cho trường hợp này. –

7

mỗi the documentation, nếu bạn cần một chữ { hoặc } để tồn tại opertation định dạng, sử dụng {{}} trong chuỗi gốc.

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