Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для URL, имени файла, имени объекта в каком-то софте и тд. Требования совместимости простые: в тексте должны быть только допустимые символы. Обычно это a-z, 0-9 и "_" или "-". То есть, только прописные буквы латинского алфавита и цифры (как пример).
Допустим, нам нужно название статьи в блоге преобразовать в slug для добавления его в URL этой статьи. Как это лучше всего сделать?
В Django по умолчанию есть готовая функция slugify для таких случаев.
Но я её никогда не использую. Почему? Потому что её недостаточно!
Приведём пример
>>> from django.utils.text import slugify
>>> slugify('This is a Title')
'this-is-a-title'
Пока всё отлично
>>> slugify('This is a "Title!"')
'this-is-a-title'
Спец символы удалились, всё хорошо.
>>> slugify('Это заголовок статьи')
''
Вот и приехали 😢. Если текст не английский то буквы просто игнорируются. Можно это поправить
>>> slugify('Это заголовок статьи', allow_unicode=True)
'это-заголовок-статьи'
Но тогда мы не вписываемся в условие. У нас появилась кириллица в тексте.
Так как я часто пишу сайты для русскоязычных пользователей эта проблема весьма актуальна. Я не использую стандартную функцию и всегда пишу свою.
Оригинал я не беру в расчёт и пишу полностью свою функцию. И так, по порядку:
🔸1. Исходный текст:
>>> text = 'Мой заголовок №10 😁!'
Взял специально посложней со специальными символами.
🔸2. Транслит
Необходимо сделать транслит всех символов в латиницу. Здесь очень выручает библиотека unidecode. Помимо простого транслита кириллицы в латиницу она умеет преобразовывать спец символы и иероглифы в текстовые аналоги.
from unidecode import unidecode
>>> unidecode("Ñ Σ ® µ ¶ ¼ 月 山")
'N S (r) u P 1/4 Yue Shan'
Очень крутая библиотека, советую👍
В нашем случае получаем такое преобразование:
>>> text = unidecode(text)
>>> print(text)
'Moi zagolovok No. 10 !'
Отличный транслит. Смайл просто удалился, хотя я ждал что-то вроде :). Ну и ладно, всë равно невалидные символы.
А еще наш код уже поддерживает любой язык, будь то хинди или корейский.
🔸4. Фильтр символов
Unidecode не занимается фильтрацией по недопустимым символам. Это мы делаем в следующем шаге через regex. Просто заменим все символы на "_" если они вне указанного диапазона.
>>> text = re.sub(r'[^a-zA-Z0-9]+', '_', text)
>>> print(text)
'Moi_zagolovok_No_10_'
Символ "+" в паттерне выручает когда несколько недопустимых символов идут рядом. Все они заменяются на один символ "_".
🔸5. Slugify
Осталось удалить лишние символы по краям и сделать нижний регистр
>>> text = text.strip('_').lower()
>>> print(text)
'moi_zagolovok_no_10'
Получаем отличный slug! 😎
🌎 Полный код в виде функции.
______________
PS. Проверку что в строке остался хоть один допустимый символ я бы вынес в отдельную функцию.
#libs#tricks#django
Наконец-то заказал себе нормальный моник Samsung на 24" в пару к одному из этих старичков, больше никаких пыток для глаз..
HDD BarraCuda 1TB в #пк и контейнер для 2.5", чтоб после прокачки одного из местных ноутов обзавестись халявным внешним HDD на пару соток гиг 🧐
и замену своим умирающим мейзу POP - недавно вышедшие Realme Buds Air, позже отпишу как они..
#device
Решил поделиться своей историей болезни (телефонов).
Встречайте! История телефонов
(#истории#device)
Всё началось где-то в классе так 3-4, тогда папа отдал мне свой телефон купив себе новую моторолу.
Я достаточно поздно получил свой первый телефон в отличии от сверстников, но позже.. Я начал стремительно обгонять, меняя их как перчатки
Вот краткий гид по прошлому моих средств связи:
–> Siemens M55 без камеры (утопленник сельского туалета в лагере)
–> Nokia 1110 оранжевый от мамы с чб экраном
–> МТС 236 за 199грн... производства ZTE (лето 2011)
–> Nokia C1-01 с камерой, бт, ЖА(Б)ВА ИГРАМИ и печеньками
–> LG GS290 на жаве, но с емкостным экраном и неубиваемым метал корпусом, МАШИНА!
Где-то в это время мне купили первый и единственный планшет на Android (за 999 грн), так что моё знакомство с мирком Fruit Ninja и подобного начался именно здесь, а не с следующего телефона.
К слову говоря, я всё ещё не могу вспомнить куда же он делся ._.
–> LG Optimus L3 [E400] (первый андроид тел.)
–> LG Optimus L5 [E612] (был слит брату как и предыдущий по низкой цене)
–> Samsung Galaxy S4 Active (единственный флагман что у меня был, куплен в конце 2013. Украден во время лыжного курорта в Словакии)
–> Sony Xperia M2 (куплен в первой половине 2015 года, утопленник Средиземноморья в Израиле)
–> Microsoft Lumia 430 (уже не помню куда он делся, но в те времена обновился до Win10M даже)
–> Doogee X5 (сука ненавижу)
–> LG Spirit [H422] (купила себе маман, я на второй день обменялся на дужи :) С ним я начал флексить в кастомы и патчи из-за нехватки встроенных 8gb)
–> Motorola Moto G3 [2015] (выпущен на 5, прошит на 8, а сейчас прошивки с 9 андроидом есть, п-поддержка)
–> Xiaomi Redmi 4 Prime [markw] (матрица пошла гулять, при этом стекло тел не пострадало, пострадали матрица и накленное стекло. Меняли раза 3 так как был брак тача, в итоге в срочном порядке перешёл на next ph.)
–> Xiaomi Mi A1 [tissot] (ааа, первое сяоми комьюнити, скорблю)
–> Xiaomi Redmi Note 5 [whyred] (комьюнити топовое, люблю этих ребят, лучшие знакомства в интернете. Уже олд, менял батарею, смаковал разные ром'ы)
–> Poco X3 NFC [surya] <– im here