2010-03-30 10 views

Respuesta

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

debería hacer muy bien. Hasta donde sé, no hay ningún método incorporado.

+0

Tenga en cuenta que esto no funciona con símbolos Unicode, p. ''éllo'' – Almar

1

En Python < 3.0 esto es bastante fácil, ya que no puede tener caracteres unicode en los identificadores. Eso debería hacer el trabajo:

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_] 'para la primera charla. – bobince

+0

Bueno, pero los identificadores pueden comenzar con un guión bajo. –

+0

Sí, estaba pensando en eso cuando escribía esto. –

12

el módulo tokenize define una expresión regular llamada Nombre

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

Para estos fines, necesita '^' + tokenize.Name + '$'. –

+0

Agregar en cheque para las palabras reservadas de python, y esto me gusta. –

+2

@Douglas S.J. De Couto: puede usar 'import keyword',' keyword.iskeyword (astring) 'para verificar si una cadena es una palabra clave, consulte su documentación [aquí] (http://docs.python.org/library/keyword.html # keyword.iskeyword). – Abbafei

1

buenas respuestas hasta el momento. Lo escribiría así.

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

Necesita permitir letras mayúsculas. Las respuestas anteriores tienen un problema similar. –

+0

@Douglas: para eso sirve la bandera 're.I'. – SilentGhost

0

lo que estoy utilizando:

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

coincidencias 're.match' desde el comienzo de la línea. – SilentGhost

1

He decidido tomar otra grieta en esto, ya que ha habido varias buenas sugerencias. Intentaré consolidarlos. Lo siguiente puede guardarse como un módulo de Python y ejecutarse directamente desde la línea de comandos. Si se ejecuta, prueba la función, por lo que es probablemente correcta (al menos en la medida en que la documentación demuestre la capacidad).

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

Todas las soluciones propuestas hasta ahora no son compatibles con Unicode o permitir que un número en el primer carácter si se ejecuta en Python 3.

Editar: las soluciones propuestas solo se deben usar en Python 2, y en Python3 se debe usar isidentifier. Aquí es una solución que debería funcionar en cualquier lugar:

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

Básicamente, se comprueba si algo se compone de (al menos 1) caracteres (incluyendo números), y después se comprueba que el primer carácter no es un número.