2008-08-18 11 views
22

Tengo un script que analiza los nombres de archivo de episodios de TV (show.name.s01e02.avi por ejemplo), toma el nombre del episodio (de la API www.thetvdb.com) y automáticamente los renombra en algo más agradable (Mostrar nombre - [01x02] .avi)Regex y Unicode

La secuencia de comandos funciona bien, eso es hasta que intente y lo use en archivos que tienen nombres de espectáculos Unicode (algo que nunca pensé, ya que todos los archivos que tengo son Inglés, por lo que en su mayoría bastante, todo cae dentro de [a-zA-Z0-9'\-])

¿Cómo puedo permitir que las expresiones regulares coincidan con los caracteres acentuados y los me gusta? Actualmente sección de configuración de la expresión regular se parece ..

config['valid_filename_chars'] = """[email protected]£$%^&*()_+=-[]{}"'.,<>`~? """ 
config['valid_filename_chars_regex'] = re.escape(config['valid_filename_chars']) 

config['name_parse'] = [ 
    # foo_[s01]_[e01] 
    re.compile('''^([%s]+?)[ \._\-]\[[Ss]([0-9]+?)\]_\[[Ee]([0-9]+?)\]?[^\\/]*$'''% (config['valid_filename_chars_regex'])), 
    # foo.1x09* 
    re.compile('''^([%s]+?)[ \._\-]\[?([0-9]+)x([0-9]+)[^\\/]*$''' % (config['valid_filename_chars_regex'])), 
    # foo.s01.e01, foo.s01_e01 
    re.compile('''^([%s]+?)[ \._\-][Ss]([0-9]+)[\.\- ]?[Ee]([0-9]+)[^\\/]*$''' % (config['valid_filename_chars_regex'])), 
    # foo.103* 
    re.compile('''^([%s]+)[ \._\-]([0-9]{1})([0-9]{2})[\._ -][^\\/]*$''' % (config['valid_filename_chars_regex'])), 
    # foo.0103* 
    re.compile('''^([%s]+)[ \._\-]([0-9]{2})([0-9]{2,3})[\._ -][^\\/]*$''' % (config['valid_filename_chars_regex'])), 
] 

Respuesta

0

\ X parece estar disponible como genérico palabra caracteres en algunos idiomas, que le permite igualar una sola Caso omiso carácter de la cantidad de bytes que ocupa. Podría ser útil.

4

en el dominio de las expresiones regulares de Jeffrey Friedl (gran libro) se menciona que se puede utilizar \ {p} Carta que coincidirá con la materia Unicode que se considera una letra.

+1

'\ {p}' Carta no es compatible con todos los motores de expresiones regulares, y en el caso de Python, que no está soportado en el motor por defecto 're'. Solo se admite en el paquete 'regex'. – nhahtdh

5

módulo de regreso de Python no soporta \ p {Carta} o \ X. Sin embargo, el new regex implementation on PyPI sí lo hace.

+1

El módulo '\ X' está roto; ellos han malentendido el estándar. No puedes simplemente usar '\ PM \ pM *' o te equivocas. Considere la cadena '" \ r \ r \ n \ x {301} A \ x {301} "'. Una [aplicación conforme] (http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) encuentra las siguientes 4 coincidencias para '\ X': 1 CP U + 000D, 2 CPs U + 000D U + 000A, 1 CP U +0301 y 2 CPs U + 0041 U + 0301. El '' PM \ pM * 'roto también encuentra 4 coincidencias, pero ** las incorrectas **: 1 CP U + 000D, 1 CP U + 000D, 2 CPs U + 000A U + 0301, y 2 CPs U + 0041 U + 0301. Usted ** DEBE ** no dividir los CRLF ni colocar Marcas en ningún punto de código '\ P {Grapheme_Base}'. – tchrist

+0

La definición de \ X se basó en el contenido de esto: http://www.regular-expressions.info/unicode.html Veré si puedo solucionarlo. – MRAB

+0

La idea original del grupo de grafemas era un poco confusa acerca de algunas cosas, por lo que los primeros en saltar en '\ X' terminaron haciéndolo un poco mal. Las implementaciones actuales de ICU y Perl lo hacen bien, e incluso usan las definiciones de clúster de grafemas extendidas: prueba 'perl5.12.0 -le 'printf"% d% v04X \ n ", length, $ _ for" \ r \ r \ " n \ x {301} A \ x {301} "= ~/\ X/g'' o posterior para ver las respuestas mejoradas. – tchrist