Регулярное выражение Python, соответствующее свойствам Юникода
-
11-09-2019 - |
Вопрос
Perl и некоторые другие современные механизмы регулярных выражений поддерживают свойства Юникода, такие как категория, в регулярных выражениях.Например.в Perl вы можете использовать \p{Ll}
для соответствия произвольной строчной букве или p{Zs}
для любого разделителя пробелов.Я не вижу поддержки этого ни в версиях Python 2.x, ни в 3.x (к сожалению).Кто-нибудь знает хорошую стратегию для получения аналогичного эффекта?Приветствуются собственные решения.
Решение
Попытался ли ты Понигурума, привязка Python к Онигурума механизм регулярных выражений?В этом движке вы можете просто сказать \p{Armenian}
чтобы соответствовать армянским символам. \p{Ll}
или \p{Zs}
тоже работай.
Другие советы
А регулярное выражение модуль (альтернатива стандартному re
модуль) поддерживает свойства кодовой точки Unicode с помощью \p{}
синтаксис.
Вы можете тщательно использовать unicodedata для каждого символа:
import unicodedata
def strip_accents(x):
return u''.join(c for c in unicodedata.normalize('NFD', x) if unicodedata.category(c) != 'Mn')
Говоря о доморощенных решениях, некоторое время назад я написал небольшую программа чтобы сделать это - преобразовать категорию Юникода, записанную как \p{...}
в диапазон значений, извлеченных из Юникода Спецификация (v.5.0.0).Поддерживаются только категории (например: L
, Zs
), и ограничено BMP.Я публикую это здесь, на случай, если кто-то найдет это полезным (хотя Онигурума действительно кажется лучшим вариантом).
Пример использования:
>>> from unicode_hack import regex
>>> pattern = regex(r'^\\p{Lu}(\\p{L}|\\p{N}|_)*')
>>> print pattern.match(u'疂_1+2').group(0)
疂_1
>>>
Вот источник.Существует также Версия JavaScript, используя те же данные.
Вы правы в том, что классы свойств Unicode не поддерживаются анализатором регулярных выражений Python.
Если бы вы хотели сделать хороший хак, который в целом был бы полезен, вы могли бы создать препроцессор, который сканирует строку на наличие таких токенов класса (\p{M}
или что-то еще) и заменяет их соответствующими наборами символов, так что, например, \p{M}
станет [\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]
, и \P{M}
станет [^\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]
.
Люди будут вам благодарны.:)
Обратите внимание, что пока \p{Ll}
не имеет эквивалента в регулярных выражениях Python, \p{Zs}
должно быть покрыто '(?u)\s'
.А (?u)
, как говорят документы: «Сделайте w, w, b, b, d, d, s и s в зависимости от базы данных свойств симвода Unicode». и \s
означает любой пробел.