2010-03-30 11 views

risposta

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

dovrebbe fare bene. Per quanto ne so non esiste alcun metodo integrato.

+0

Si noti che questo non funziona con i simboli Unicode, ad es. ''éllo'' – Almar

1

In Python < 3.0 questo è abbastanza facile, in quanto non è possibile avere caratteri unicode negli identificatori. Che dovrebbe fare il lavoro:

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_] 'per primo carattere. – bobince

+0

Buono, ma gli identificatori possono iniziare con un trattino basso. –

+0

Sì, ci stavo pensando quando stavo scrivendo questo. –

12

il modulo tokenize definisce un'espressione regolare chiamato Nome

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

Per questi scopi, è necessario '^' + tokenize.Name + '$'. –

+0

Aggiungi sotto controllo le parole riservate di python e mi piace. –

+2

@Douglas S.J. De Couto - puoi usare 'import keyword',' keyword.iskeyword (astring) 'per verificare se una stringa è una parola chiave, vedere la sua documentazione [qui] (http://docs.python.org/library/keyword.html # keyword.iskeyword). – Abbafei

1

buone risposte finora. Lo scriverei in questo modo

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

Necessario per consentire lettere maiuscole. Le risposte sopra hanno problemi simili. –

+0

@Douglas: ecco a cosa serve la bandiera 're.I'. – SilentGhost

0

quello che sto usando:

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

corrispondenza 're.match' dall'inizio della riga. – SilentGhost

1

ho deciso di prendere un'altra crepa a questo, dal momento che ci sono stati diversi buoni suggerimenti. Cercherò di consolidarli. Quanto segue può essere salvato come modulo Python ed eseguito direttamente dalla riga di comando. Se eseguito, verifica la funzione, quindi è provabilmente corretto (almeno nella misura in cui la documentazione dimostra la capacità).

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

Tutte le soluzioni finora proposte non supportano Unicode o consentire a un numero nel primo carattere se eseguito su Python 3.

Modifica: le soluzioni proposte devono essere utilizzate solo su Python 2 e su Python3 deve essere utilizzato isidentifier. Ecco una soluzione che dovrebbe lavorare ovunque:

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

In sostanza, si verifica se qualcosa è composto da (almeno 1) caratteri (compresi i numeri), e poi si verifica che il primo carattere non è un numero.

Problemi correlati