Регулярное выражение и юникод

У меня есть сценарий, который анализирует имена файлов телевизионных эпизодов (например, show.name.s01e02.avi), берет имя эпизода (из API www.thetvdb.com) и автоматически переименовывает их во что-то более приятное (Show Name - [01x02 ] .avi)

Скрипт работает нормально, пока вы не попробуете использовать его для файлов с отображаемыми именами Unicode (о чем я никогда особо не задумывался, так как все файлы, которые у меня есть, на английском языке, так что почти все они попадают внутрь [a-zA-Z0-9'\-] )

Как разрешить регулярным выражениям совпадать с акцентированными символами и т.п.? В настоящее время раздел конфигурации регулярного выражения выглядит так ..

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'])),
]

Ответов (4)

Решение

Используйте поддиапазон того, [\u0000-\uFFFF] что вы хотите.

Вы также можете использовать re.UNICODE флаг компиляции. В документах говорится, что если UNICODE установлено, \w будет соответствовать символам [0-9_] плюс все, что классифицируется как буквенно-цифровое в базе данных свойств символов Юникода.

См. Также http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-05/2560.html .

В «Освоении регулярных выражений» от Джеффри Фридла (отличная книга) упоминается, что вы можете использовать \ p {Letter}, который будет соответствовать юникодному материалу, который считается буквой.

\ X, кажется, доступен как общий символ слова в некоторых языках, он позволяет вам сопоставлять один символ независимо от того, сколько байтов он занимает. Может быть полезно.

Модуль Python re не поддерживает \ p {Letter} или \ X. Однако новая реализация регулярного выражения в PyPI делает это.