¿Puedo mezclar clases de caracteres en Python RegEx?

Las secuencias especiales (clases de caracteres) en Python RegEx son escapes como \w o \d que coinciden con un conjunto de caracteres.

En mi caso, necesito poder hacer coincidir todos los caracteres alfanuméricos excepto los números.

Es decir, \w minus \d .

Necesito usar la secuencia especial \w porque estoy tratando con caracteres que no son ASCII y necesito hacer coincidir símbolos como “Æ” y “Ø”.

Uno podría pensar que podría usar esta expresión: [\w^\d] pero no parece coincidir con nada y no estoy seguro de por qué.

En resumen, ¿cómo puedo mezclar (agregar / restar) secuencias especiales en Python Regular Expressions?


EDIT : Accidentalmente usé [\W^\d] lugar de [\w^\d] . De hecho, esto último hace coincidir algo, incluyendo paréntesis y comas que no son caracteres alfanuméricos en lo que a mí respecta.

Puede usar r"[^\W\d]" , es decir. Invertir la unión de no alfanuméricos y números.

No puedes restar clases de caracteres, no.

Lo mejor es usar el nuevo módulo de regex , configurado para reemplazar el módulo de re actual en python. Admite clases de caracteres basadas en las propiedades de Unicode:

 \p{IsAlphabetic} 

Esto coincidirá con cualquier carácter que la especificación de Unicode diga que es un carácter alfabético.

Aún mejor, regex soporta la resta de clases de caracteres; ve estas clases como conjuntos y le permite crear una diferencia con el operador -- :

 [\w--\d] 

coincide con todo en \w excepto cualquier cosa que también coincida con \d .

Puede excluir clases usando una aserción de búsqueda negativa negativa, como r'(?!\d)[\w]' para que coincida con un carácter de palabra, excluyendo los dígitos. Por ejemplo:

 >>> re.search(r'(?!\d)[\w]', '12bac') <_sre.SRE_Match object at 0xb7779218> >>> _.group(0) 'b' 

Para excluir más de un grupo, puede usar la syntax [...] habitual en la afirmación de búsqueda anticipada, por ejemplo, r'(?![0-5])[\w]' coincidiría con cualquier carácter alfanumérico excepto los dígitos 0 -5.

Al igual que con [...] , la construcción anterior coincide con un solo carácter. Para hacer coincidir varios caracteres, agregue un operador de repetición:

 >>> re.search(r'((?!\d)[\w])+', '12bac15') <_sre.SRE_Match object at 0x7f44cd2588a0> >>> _.group(0) 'bac' 

No creo que pueda combinar directamente los juegos de caracteres (booleanos y) en una sola expresión regular, ya sea que uno sea negado o no. De lo contrario, simplemente podría haber combinado [^\d] y \w .

Nota: el ^ debe estar al principio del conjunto y se aplica a todo el conjunto. De los documentos: “Si el primer carácter del conjunto es ‘^’, todos los caracteres que no están en el conjunto serán coincidentes”. Su conjunto [\w^\d] intenta hacer coincidir un carácter alfanumérico, seguido de un símbolo de intercalación, seguido de un dígito. Puedo imaginar que eso tampoco encaja con nada.

Lo haría en dos pasos, combinando efectivamente las expresiones regulares. Primero haga coincidir con no dígitos (expresiones regulares internas), luego haga coincidir con caracteres alfanuméricos:

 re.search('\w+', re.search('([^\d]+)', s).group(0)).group(0) 

o variaciones de este tema.

Tenga en cuenta que debería rodear esto con un try: except: block, ya que lanzará un AttributeError: 'NoneType' object has no attribute 'group' en caso de que falle uno de los dos regexes. Pero puede, por supuesto, dividir esta única línea en unas pocas líneas más.