python-re: ¿Cómo hago coincidir un carácter alfa?

¿Cómo puedo relacionar un carácter alfa con una expresión regular? Quiero un carácter que esté en \w pero que no esté en \d . Lo quiero compatible con Unicode, por eso no puedo usar [a-zA-Z] .

Tus dos primeras frases se contradicen entre sí. “in \w pero no está en \d ” incluye guión bajo. Supongo que a partir de tu tercera frase no quieres subrayar.

Usar un diagtwig de Venn en la parte posterior de un sobre ayuda. Veamos lo que NO queremos:

(1) los caracteres que no coinciden con \w (es decir, no quieren nada que no sea alfa, dígitos o guión bajo) => \W
(2) dígitos => \d
(3) subrayado => _

Entonces, lo que no queremos es nada en la clase de caracteres [\W\d_] y, en consecuencia, lo que queremos es algo en la clase de caracteres [^\W\d_]

Aquí hay un ejemplo simple (Python 2.6).

 >>> import re >>> rx = re.compile("[^\W\d_]+", re.UNICODE) >>> rx.findall(u"abc_def,k9") [u'abc', u'def', u'k'] 

La exploración adicional revela algunas peculiaridades de este enfoque:

 >>> import unicodedata as ucd >>> allsorts =u"\u0473\u0660\u06c9\u24e8\u4e0a\u3020\u3021" >>> for x in allsorts: ... print repr(x), ucd.category(x), ucd.name(x) ... u'\u0473' Ll CYRILLIC SMALL LETTER FITA u'\u0660' Nd ARABIC-INDIC DIGIT ZERO u'\u06c9' Lo ARABIC LETTER KIRGHIZ YU u'\u24e8' So CIRCLED LATIN SMALL LETTER Y u'\u4e0a' Lo CJK UNIFIED IDEOGRAPH-4E0A u'\u3020' So POSTAL MARK FACE u'\u3021' Nl HANGZHOU NUMERAL ONE >>> rx.findall(allsorts) [u'\u0473', u'\u06c9', u'\u4e0a', u'\u3021'] 

U + 3021 (HANGZHOU NUMERAL ONE) se trata como numérico (por lo tanto, coincide con \ w) pero parece que Python interpreta “dígito” para significar “dígito decimal” (categoría Nd), por lo que no coincide con \ d

U + 2438 (LETRA PEQUEÑA LATINA CIRCLADA) no coincide \ w

Todos los ideogtwigs CJK se clasifican como “letras” y, por lo tanto, coinciden con \ w

Si alguno de los 3 puntos anteriores es una preocupación o no, ese enfoque es el mejor que obtendrá del módulo de re como se lanzó actualmente. La syntax como \ p {letra} está en el futuro.

Qué pasa:

 \p{L} 

Puede usar este documento como referencia: Unicode Regular Expressions

EDITAR: Parece que Python no maneja expresiones Unicode . Eche un vistazo a este enlace: el manejo de caracteres acentuados con Python Regular Expressions – [AZ] simplemente no es lo suficientemente bueno (ya no está activo, enlace al archivo de Internet)

Otras referencias:

  • re.UNICODE
  • Python y expresión regular con Unicode.
  • Estándar Técnico Unicode # 18: Expresiones Regulares de Unicode

Para la posteridad, aquí están los ejemplos en el blog:

 import re string = 'riché' print string riché richre = re.compile('([Az]+)') match = richre.match(string) print match.groups() ('rich',) richre = re.compile('(\w+)',re.LOCALE) match = richre.match(string) print match.groups() ('rich',) richre = re.compile('([é\w]+)') match = richre.match(string) print match.groups() ('rich\xe9',) richre = re.compile('([\xe9\w]+)') match = richre.match(string) print match.groups() ('rich\xe9',) richre = re.compile('([\xe9-\xf8\w]+)') match = richre.match(string) print match.groups() ('rich\xe9',) string = 'richéñ' match = richre.match(string) print match.groups() ('rich\xe9\xf1',) richre = re.compile('([\u00E9-\u00F8\w]+)') print match.groups() ('rich\xe9\xf1',) matched = match.group(1) print matched richéñ 

Puede usar una de las siguientes expresiones para hacer coincidir una sola letra:

 (?![\d_])\w 

o

 \w(? 

Aquí coincido con \w , pero verifique que [\d_] no coincida antes / después de eso.

De los documentos:

 (?!...) Matches if ... doesn't match next. This is a negative lookahead assertion. For example, Isaac (?!Asimov) will match 'Isaac ' only if it's not followed by 'Asimov'. (?