¿Cuál es la mejor manera de quitar todos los caracteres no alfanuméricos de una cadena, usando Python?
Las soluciones presentadas en la variante PHP de esta pregunta probablemente funcionarán con algunos ajustes menores, pero no me parecen muy 'pitónicas'.
Para el registro, no solo quiero quitar puntos y comas (y otros signos de puntuación), sino también citas, corchetes, etc.

Respuestas:
Acabo de cronometrar algunas funciones por curiosidad. En estas pruebas, estoy eliminando caracteres no alfanuméricos de la cadena
string.printable(parte delstringmódulo incorporado ). El uso de compilado'[\W_]+'ypattern.sub('', str)resultó ser el más rápido.fuente
valid_characters = string.ascii_letters + string.digitsseguido porjoin(ch for ch in string.printable if ch in valid_characters)y fue 6 microsegundos más rápido que laisalnum()opción. Sin embargo, aún mucho más lento que lapattern.sub('', string.printable)lugar, ¡tonto llamar a re.sub cuando tienes un objeto RE! -).re.compile('[\W_]+', re.UNICODE)para hacerlo unicode seguro.Expresiones regulares al rescate:
fuente
\Wtambién mantendrá guiones bajos.Use el método str.translate () .
Presumiendo que harás esto a menudo:
(1) Una vez, cree una cadena que contenga todos los caracteres que desea eliminar:
(2) Cada vez que quieras apretar una cuerda:
El costo de instalación probablemente se compara favorablemente con re.compile; el costo marginal es mucho más bajo:
Nota: El uso de string.printable como datos de referencia proporciona al patrón '[\ W _] +' una ventaja injusta ; todos los caracteres no alfanuméricos están en un grupo ... en los datos típicos habría más de una sustitución que hacer:
Esto es lo que sucede si le das un poco más de trabajo a re.sub:
fuente
string.punctuationEn lugar de''.join(c for c in map(chr, range(256)) if not c.isalnum())strobjetos pero no paraunicodeobjetos..join()?Tu podrías intentar:
fuente
fuente
Qué tal si:
Esto funciona mediante el uso de la comprensión de la lista para producir una lista de los caracteres
InputStringsi están presentes en las cadenasascii_lettersy combinadasdigits. Luego une la lista en una cadena.fuente
Como resultado de algunas otras respuestas aquí, ofrezco una forma realmente simple y flexible de definir un conjunto de caracteres a los que desea limitar el contenido de una cadena. En este caso, permito alfanuméricos MÁS guiones y guiones bajos. Simplemente agregue o elimine caracteres de mi
PERMITTED_CHARSsegún convenga a su caso de uso.fuente
string.digits + string.ascii_letters + '_-'.SPECIAL_CHARS = '_-'y luego usarlasstring.digits + string.ascii_letters + SPECIAL_CHARSfuente
e for e in senty comprueba mediante unaif e.isalpha()declaración si el carácter actual es un símbolo alfabético, si es así, lo une a lasentvariable víasent = "".join()y todos los símbolos no alfabéticos serán reemplazados por""(cadena vacía) porque de lajoinfunciónfuente
Temporización con cadenas aleatorias de imprimibles ASCII:
Resultado (Python 3.7):
str.maketrans&str.translatees el más rápido, pero incluye todos los caracteres no ASCII.re.compile&pattern.subes más lento, pero de alguna manera es más rápido que''.join&filter.fuente
Si entendí correctamente, la forma más fácil es usar expresiones regulares, ya que le brinda mucha flexibilidad, pero el otro método simple es usarlo para el seguimiento del bucle es el código con el ejemplo. También conté la aparición de palabras y las almacené en el diccionario.
por favor califique esto si esta respuesta es útil!
fuente