2010-02-23 39 views
5

Tôi là người mới sử dụng Python. Tôi muốn viết một biểu thức chính quy để kiểm tra tên. Chuỗi đầu vào của tôi có thể chứa a-z, A-Z, 0-9 và '_', nhưng phải bắt đầu bằng a-z hoặc A-Z (không phải 0-9 và '_'). Tôi muốn viết một biểu thức chính quy cho việc này. Tôi đã thử, nhưng không có gì phù hợp hoàn hảo.Làm cách nào để sử dụng cụm từ thông dụng để khớp với tên?

Khi chuỗi đầu vào tuân theo quy tắc biểu thức chính quy, tôi có thể tiến hành thêm, nếu không thì loại bỏ chuỗi đó.

+0

là chuỗi rỗng được phép? – Svante

+1

Bây giờ nó là gì, '-' hoặc' _'? – Svante

+0

chuỗi rỗng không được phép. "_" đây là dấu gạch ngang không gạch ngang – user279315

Trả lời

4
>>> import re 

>>> re.match("[a-zA-Z][\w-]*$","A") 
<_sre.SRE_Match object at 0x00932E20> 

>>> re.match("[a-zA-Z][\w-]*$","A_B") 
<_sre.SRE_Match object at 0x008CA950> 

>>> re.match("[a-zA-Z][\w-]*$","0A") 
>>> 
>>> re.match("[a-zA-Z][\w-]*$","!A_B") 
>>> 

Note: OP đề cập string cannot start from (0-9 and "_")., rõ ràng _ có thể trong văn bản. Thats lý do tại sao tôi đang sử dụng \w

Note2: Nếu bạn không muốn trận đấu kết thúc chuỗi với \n, bạn có thể sử dụng \Z thay vì $ như John Machin đề cập.

+0

'[a-zA-Z] [\ w -] * $' Regex này sai vì nó sẽ khớp với chuỗi bắt đầu bằng bất kỳ thứ gì. Hầu như ở đó, mặc dù chỉ cần một circumflex lúc đầu. – Mikuso

+2

@Mikuso, 're.match()' chỉ khớp với từ đầu chuỗi. 'lại.tìm kiếm() 'sẽ cần dấu mũ –

+0

Sai; nó khớp với "A \ n" –

5

Dưới đây là một câu trả lời cho câu hỏi của bạn:

Giải thích mà bạn muốn _ (không -), điều này sẽ thực hiện công việc:

>>> tests = ["a", "A", "a1", "a_1", "1a", "_a", "a\n", "", "z_"] 
>>> for test in tests: 
... print repr(test), bool(re.match(r"[A-Za-z]\w*\Z", test)) 
... 
'a' True 
'A' True 
'a1' True 
'a_1' True 
'1a' False 
'_a' False 
'a\n' False 
'' False 
'z_' True 
>>> 

Stoutly cưỡng lại sự cám dỗ để sử dụng $; đây là lý do:

Xin chào, xin chào, sử dụng $ là sai, sử dụng \Z thay

>>> re.match(r"[a-zA-Z][\w-]*$","A") 
<_sre.SRE_Match object at 0x00BAFE90> 
>>> re.match(r"[a-zA-Z][\w-]*$","A\n") 
<_sre.SRE_Match object at 0x00BAFF70> # WRONG; SHOULDN'T MATCH 
>>> 

>>> re.match(r"[a-zA-Z][\w-]*\Z","A") 
<_sre.SRE_Match object at 0x00BAFE90> 
>>> re.match(r"[a-zA-Z][\w-]*\Z","A\n") 
>>> # CORRECT: NO MATCH 

The Fine Manual nói:

'$'
Trận cuối của chuỗi hoặc ngay trước khi dòng mới ở cuối chuỗi [nhấn mạnh của tôi] và trong chế độ MULTILINE cũng khớp với một dòng mới. foo khớp với cả ‘foo’ và ‘foobar’, trong khi cụm từ thông dụng foo $ chỉ khớp với ‘foo’. Thú vị hơn, tìm kiếm foo. $ Trong 'foo1 \ nfoo2 \ n' khớp với ‘foo2’ bình thường, nhưng ‘foo1’ ở chế độ MULTILINE; tìm kiếm một $ duy nhất trong 'foo \ n' sẽ tìm thấy hai kết quả phù hợp (trống): một ở ngay trước dòng mới và một ở cuối chuỗi.

\ Z
Matches chỉ ở phần cuối của chuỗi.

=== Và bây giờ cho một cái gì đó hoàn toàn khác nhau ===

>>> import string 
>>> letters = set(string.ascii_letters) 
>>> ok_chars = letters | set(string.digits + "_") 
>>> 
>>> def is_valid_name(strg): 
...  return strg and strg[0] in letters and all(c in ok_chars for c in strg) 
... 
>>> for test in tests: 
...  print repr(test), repr(is_valid_name(test)) 
... 
'a' True 
'A' True 
'a1' True 
'a_1' True 
'1a' False 
'_a' False 
'a\n' False 
'' '' 
'z_' True 
>>> 
-1

Đây là một cách phi tái

import string 
flag=0 
mystring="abcadsf123" 
if not mystring[0] in string.digits+"_": 
    for c in mystring: 
     if not c in string.letters+string.digits+"-": 
      flag=1 
    if flag: print "%s not ok" % mystring 
    else: print "%s ok" % mystring 
else: print "%s starts with digits or _" % mystring 
+0

(1) Người hỏi không nói rằng anh ta muốn kết quả phụ thuộc vào miền địa phương; anh ấy nói anh ấy muốn [a-zA-Z], vì vậy hãy sử dụng string.ascii_letters (2) treo nếu đầu vào là "" (3) điều cờ là kinh khủng –

Các vấn đề liên quan