Python 3 ha un metodo stringa chiamato str.isidentifier
Come si può ottenere la funzionalità Python di isidentifer() in Python 2.6?
Come posso ottenere funzionalità simili in Python 2.6, a meno di riscrivere la mia espressione regolare, ecc.?
Python 3 ha un metodo stringa chiamato str.isidentifier
Come si può ottenere la funzionalità Python di isidentifer() in Python 2.6?
Come posso ottenere funzionalità simili in Python 2.6, a meno di riscrivere la mia espressione regolare, ecc.?
re.match(r'[a-z_]\w*$', s, re.I)
dovrebbe fare bene. Per quanto ne so non esiste alcun metodo integrato.
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
' [a-z_] 'per primo carattere. – bobince
Buono, ma gli identificatori possono iniziare con un trattino basso. –
Sì, ci stavo pensando quando stavo scrivendo questo. –
il modulo tokenize definisce un'espressione regolare chiamato Nome
import re, tokenize, keyword
re.match(tokenize.Name + '$', somestr) and not keyword.iskeyword(somestr)
Per questi scopi, è necessario '^' + tokenize.Name + '$'. –
Aggiungi sotto controllo le parole riservate di python e mi piace. –
@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
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
Necessario per consentire lettere maiuscole. Le risposte sopra hanno problemi simili. –
@Douglas: ecco a cosa serve la bandiera 're.I'. – SilentGhost
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
corrispondenza 're.match' dall'inizio della riga. – SilentGhost
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()
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.
Si noti che questo non funziona con i simboli Unicode, ad es. ''éllo'' – Almar