Tengo que repetir varias veces usando este código, ¿hay una mejor manera?

item = '!@#$abc-123-4;5.def)(*&^;\n'

O

'!@#$abc-123-4;5.def)(*&^;\n_'

O

'!@#$abc-123-4;5.def)_(*&^;\n_'

El que tengo así no funcionó

item = re.sub('^\W|\W$', '', item)

Esperar

abc-123-4;5.def

El objetivo final es mantener solo eliminar todo lo que no sea [a-zA-Z0-9] de ambos extremos mientras se mantienen los caracteres en el medio. La primera y la última letra están en la clase [a-zA-Z0-9]

12
Gang 10 may. 2019 a las 03:47

3 respuestas

La mejor respuesta

Para recortar caracteres que no sean palabras (\W superior) desde el inicio / final, pero también agregue el guión bajo que pertenece a caracteres de palabras [A-Za-z0-9_] puede soltar el _ en una clase de caracteres junto con \W.

^[\W_]+|[\W_]+$

Ver demostración en regex101. Esto es muy similar a la respuesta de @Caustin y al comentario de @ sln.


Para obtener la demostración inversa y hacer coincidir todo, desde el primero hasta el último carácter alfanumérico:

[^\W_](?:.*[^\W_])?

O con alternancia demo (|[^\W_] para cadenas que tienen solo un alnum).

[^\W_].*[^\W_]|[^\W_]

Ambos con re.DOTALL para cadenas multilínea. Sabores de expresiones regulares sin probar [\s\S]* en lugar de .* demo

6
bobble bubble 24 jun. 2019 a las 09:19

En primer lugar, puede cortar algunos casos muy especiales eliminando los caracteres de escape :

item = re.sub(r'\\[abnrt]', '', item)

Después de eso, eliminemos el carácter _ de \W, de lo que obtienes [^a-zA-Z0-9].

Su expresión regular final será: (^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)

item = re.sub(r'(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)', '', item)

Ver explicación ...

enter image description here

Aquí puedes visualizar tu expresión regular ...

4
Norbert Incze 18 may. 2019 a las 11:06

Puede lograr esto utilizando el carácter de quilate ^ al comienzo de un conjunto de caracteres para negar su contenido. [^a-zA-Z0-9] coincidirá con cualquier cosa que no sea una letra o un número.

^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$
10
revo 17 may. 2019 a las 20:44