2010-02-23 28 views
5

Jestem nowicjuszem w Pythonie. Chcę napisać wyrażenie regularne do sprawdzania nazw. Mój ciąg wejściowy może zawierać a-z, A-Z, 0-9 i "_", ale powinien zaczynać się od a-z lub A-Z (nie 0-9 i "_"). Chcę napisać dla tego wyrażenie regularne. Próbowałem, ale nic nie pasowało idealnie.Jak użyć wyrażenia regularnego do dopasowania nazwy?

Po wprowadzeniu ciągu wejściowego zgodnego z regułami wyrażenia regularnego, mogę przejść dalej, w przeciwnym razie odrzucić ten ciąg.

+0

jest pusty ciąg być dozwolone? – Svante

+1

Który to teraz, '-' lub' _'? – Svante

+0

pusty ciąg znaków nie może być dozwolony. "_" to nie jest myślnik – user279315

Odpowiedz

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

Uwaga OP wspomniano string cannot start from (0-9 and "_")., najwyraźniej _ może być w tekście. To dlatego używam \w

UWAGA2: Jeśli nie chcesz mecz ciąg kończy \n, można użyć \Z zamiast $ jak wspomniano John Machin.

+0

'[a-zA-Z] [\ w -] * $' To wyrażenie jest niepoprawne, ponieważ dopasuje ciąg rozpoczynający się od czegokolwiek. Prawie jednak, po prostu potrzebuje okrętu na początku. – Mikuso

+2

@Mikuso, 're.match()' dopasowuje tylko od początku łańcucha. 're.search() 'potrzebowałby opiekuna –

+0

Wrong; pasuje do "A \ n" –

5

Oto odpowiedź na pytanie:

wykładni tego chcesz _ (nie -), to powinno załatwić sprawę:

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

stanowczo oprzeć się pokusie korzystania $; oto dlaczego:

Halo, halo, używając $ jest źle, używać \Z zamiast

>>> 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 mówi:

'$'
Dopasowuje koniec łańcucha lub tuż przed znak nowej linii na końcu ciągu znaków [mój nacisk], aw trybie MULTILINE również dopasowuje przed znakiem nowej linii. foo dopasowuje zarówno "foo", jak i "foobar", podczas gdy wyrażenie regularne foo $ dopasowuje tylko "foo". Co ciekawsze, szukanie foo. $ W 'foo1 \ nfoo2 \ n' dopasowuje 'foo2' normalnie, ale 'foo1' w trybie MULTILINE; poszukiwanie pojedynczego $ in 'foo \ n' znajdzie dwa (puste) dopasowania: jeden tuż przed znakiem nowej linii i jeden na końcu łańcucha.

i

\ Z
Mecze tylko na końcu łańcucha.

=== A teraz coś z zupełnie innej beczki ===

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

tu jest zakaz ponownego sposób

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) Pytający nie powiedział, że chce wyników zależnych od lokalizacji; powiedział, że chce [a-zA-Z], więc użyj string.ascii_letters (2), jeśli wejście jest "" (3) flaga jest okropna –

Powiązane problemy