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

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

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

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

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'])),
]
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
25
0
15 734
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Используйте поддиапазон [\u0000-\uFFFF] по своему усмотрению.

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

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

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

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

\p{Letter} поддерживается не всеми механизмами регулярных выражений, а в случае Python он не поддерживается в модуле re по умолчанию. Поддерживается только в пакете regex.

nhahtdh 11.11.2015 12:50

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

\X этого модуля сломан; они неправильно поняли стандарт. Вы не можете просто использовать \PM\pM*, иначе вы ошибетесь. Рассмотрим строку "\r\r\n\x{301}A\x{301}". соответствующее приложение находит следующие 4 совпадения для \X: 1 CP U + 000D, 2 CP U + 000D U + 000A, 1 CP U + 0301 и 2 CP U + 0041 U + 0301. Сломанный \PM\pM* также находит 4 совпадения, но неправильные: 1 CP U + 000D, 1 CP U + 000D, 2 CP U + 000A U + 0301 и 2 CP U + 0041 U + 0301. Вы ДОЛЖЕН не разбиваете CRLF и не размещаете Знаки на каких-либо кодовых точках \P{Grapheme_Base}.

tchrist 02.04.2011 05:29

Определение \ X было основано на содержимом этого: regular-expressions.info/unicode.html Я посмотрю, смогу ли я это исправить.

MRAB 02.04.2011 05:37

Первоначальная идея кластера графем была немного запутана в нескольких вещах, поэтому первые люди, которые перешли на \X, в конечном итоге сделали это немного неправильно. Текущие реализации ICU и Perl все делают правильно и даже используют расширенные определения кластеров графем: попробуйте perl5.12.0 -le 'printf "%d %v04X\n", length, $_ for "\r\r\n\x{301}A\x{301}" =~ /\X/g' или более позднюю версию, чтобы увидеть улучшенные ответы.

tchrist 02.04.2011 06:00

@tchrist: Кажется, сейчас это исправлено (или никогда не ломалось). python -c'import regex as re; print(re.findall(u"\X", u"\r\r\n\u0301A\u0301"))' печатает ожидаемые результаты: [u'\r', u'\r\n', u'\u0301', u'A\u0301']

jfs 21.12.2013 07:10

@ J.F.Sebastian Я знаю, что это исправили. Я долго переписывался с автором. Он классный.

tchrist 21.12.2013 07:57

Другие вопросы по теме