2010-03-30 10 views

Odpowiedz

2
re.match(r'[a-z_]\w*$', s, re.I) 

powinien zrobić ładnie. O ile mi wiadomo, nie ma żadnej wbudowanej metody.

+0

Należy zauważyć, że nie działa to w przypadku symboli Unicode, np. ''éllo'' – Almar

1

W Pythonie < 3.0 jest to całkiem proste, ponieważ nie można mieć znaków Unicode w identyfikatorach. To powinno załatwić pracę:

import re 
import keyword 

def isidentifier(s): 
    if s in keyword.kwlist: 
     return False 
    return re.match(r'^[a-z_][a-z0-9_]*$', s, re.I) is not None 
+0

' [a-z_] 'dla pierwszego znaku. – bobince

+0

Dobrze, ale identyfikatory można rozpoczynać od podkreślenia. –

+0

Tak, myślałem o tym, kiedy to pisałem. –

12

moduł tokenize definiuje regexp nazwie Nazwa

import re, tokenize, keyword 
re.match(tokenize.Name + '$', somestr) and not keyword.iskeyword(somestr) 
+3

Do tych celów potrzebujesz '^' + tokenize.Name + '$'. –

+0

Dodaj do wyboru słów zastrzeżonych python, i podoba mi się to. –

+2

@Douglas S.J. De Couto - możesz użyć 'importuj słowo kluczowe',' keyword.iskeyword (astring) ', aby sprawdzić, czy ciąg znaków jest słowem kluczowym, zobacz jego dokumentację [tutaj] (http://docs.python.org/library/keyword.html # keyword.iskeyword). – Abbafei

1

Dobre odpowiedzi tak daleko. Napisałbym to w ten sposób.

import keyword 
import re 

def isidentifier(candidate): 
    "Is the candidate string an identifier in Python 2.x" 
    is_not_keyword = candidate not in keyword.kwlist 
    pattern = re.compile(r'^[a-z_][a-z0-9_]*$', re.I) 
    matches_pattern = bool(pattern.match(candidate)) 
    return is_not_keyword and matches_pattern 
+0

Konieczność zezwolenia na duże litery. Powyższe odpowiedzi mają podobny problem. –

+0

@Douglas: do tego służy flaga 're.I'. – SilentGhost

0

Co Używam:

def is_valid_keyword_arg(k): 
    """ 
    Return True if the string k can be used as the name of a valid 
    Python keyword argument, otherwise return False. 
    """ 
    # Don't allow python reserved words as arg names 
    if k in keyword.kwlist: 
     return False 
    return re.match('^' + tokenize.Name + '$', k) is not None 
+0

're.match' dopasowuje od początku linii. – SilentGhost

1

Zdecydowałem się zrobić kolejne pęknięcie na to, ponieważ było kilka dobrych sugestii. Spróbuję je skonsolidować. Poniższe można zapisać jako moduł Pythona i uruchomić bezpośrednio z wiersza poleceń. Po uruchomieniu testuje funkcję, więc jest to poprawne (przynajmniej w takim zakresie, w jakim dokumentacja demonstruje możliwości).

import keyword 
import re 
import tokenize 

def isidentifier(candidate): 
    """ 
    Is the candidate string an identifier in Python 2.x 
    Return true if candidate is an identifier. 
    Return false if candidate is a string, but not an identifier. 
    Raises TypeError when candidate is not a string. 

    >>> isidentifier('foo') 
    True 

    >>> isidentifier('print') 
    False 

    >>> isidentifier('Print') 
    True 

    >>> isidentifier(u'Unicode_type_ok') 
    True 

    # unicode symbols are not allowed, though. 
    >>> isidentifier(u'Unicode_content_\u00a9') 
    False 

    >>> isidentifier('not') 
    False 

    >>> isidentifier('re') 
    True 

    >>> isidentifier(object) 
    Traceback (most recent call last): 
    ... 
    TypeError: expected string or buffer 
    """ 
    # test if candidate is a keyword 
    is_not_keyword = candidate not in keyword.kwlist 
    # create a pattern based on tokenize.Name 
    pattern_text = '^{tokenize.Name}$'.format(**globals()) 
    # compile the pattern 
    pattern = re.compile(pattern_text) 
    # test whether the pattern matches 
    matches_pattern = bool(pattern.match(candidate)) 
    # return true only if the candidate is not a keyword and the pattern matches 
    return is_not_keyword and matches_pattern 

def test(): 
    import unittest 
    import doctest 
    suite = unittest.TestSuite() 
    suite.addTest(doctest.DocTestSuite()) 
    runner = unittest.TextTestRunner() 
    runner.run(suite) 

if __name__ == '__main__': 
    test() 
0

Wszystkie rozwiązania proponowane dotychczas nie obsługują Unicode lub pozwolić na numer w pierwszej char jeśli uruchomiony na Pythonie 3.

Edycja: proponowane rozwiązania powinny być używane tylko w Pythonie 2, a na Pythonie 3 należy używać isidentifier. Oto rozwiązanie, które powinno działać w dowolnym miejscu:

re.match(r'^\w+$', name, re.UNICODE) and not name[0].isdigit() 

Zasadniczo, to sprawdza czy coś składa się z (co najmniej 1) znaki (w tym numerów), a następnie sprawdza, że ​​pierwszy znak nie jest liczbą.

Powiązane problemy