Regex e Unicode
-
08-06-2019 - |
Pergunta
Eu tenho um script que analisa os nomes dos arquivos dos episódios de TV (show.name.s01e02.avi por exemplo), pega o nome do episódio (da API www.thetvdb.com) e os renomeia automaticamente para algo mais legal (Nome do programa - [01x02 ].avi)
O script funciona bem, até você tentar usá-lo em arquivos que possuem nomes de exibição Unicode (algo que eu nunca pensei, já que todos os arquivos que tenho são em inglês, então quase todos se enquadram [a-zA-Z0-9'\-]
)
Como posso permitir que as expressões regulares correspondam a caracteres acentuados e similares?Atualmente a seção de configuração do regex se parece com ..
config['valid_filename_chars'] = """0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@£$%^&*()_+=-[]{}"'.,<>`~? """
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'])),
]
Solução
Use um subintervalo de [\u0000-\uFFFF]
para o que você quer.
Você também pode usar o re.UNICODE
sinalizador de compilação. Os documentos diga que se UNICODE
está definido, \w
combinará com os personagens [0-9_]
mais tudo o que for classificado como alfanumérico no banco de dados de propriedades de caracteres Unicode.
Veja também http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-05/2560.html.
Outras dicas
O módulo re do Python não suporta \p{Letter} ou \X.No entanto, o nova implementação de regex no PyPI faz.
Em Mastering Regular Expressions de Jeffrey Friedl (ótimo livro), é mencionado que você pode usar \p{Letter} que corresponderá ao material Unicode que é considerado uma letra.
\X parece estar disponível como um caractere de palavra genérico em alguns idiomas; permite combinar um único caractere, independentemente de quantos bytes ele ocupa.Pode ser útil.