Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
Russia's Navalny says prison has changed his status to 'terrorist'
Jailed Kremlin critic Alexei Navalny said on Monday that a prison commission had designated him an extremist and a terrorist, but officially no longer regarded him as an escape risk.
#AlexeiNavalny#Kremlin#Russia#News#Reuters
Subscribe: http://smarturl.it/reuterssubscribe
Reuters brings you the latest business, finance and breaking news video from around the globe. Our reputation for accuracy and impartiality is unparalleled.
Get the latest news on: http://reuters.com/
Follow Reuters on Facebook: https://www.facebook.com/Reuters
Follow Reuters on Twitter: https://twitter.com/Reuters
Follow Reuters on Instagram: https://www.instagram.com/reuters/?hl=en
➖@reutersworldchannel➖
Mi spiace, sinceramente, dover insistere sulla vicenda di quest'uomo. Anche perché credo sia giusto nutrire pietà dinanzi alla morte di una persona, soprattutto se avvenuta durante una carcerazione così dura.
Nessuno nega le responsabilità, in un modo o nell'altro, di Putin rispetto alla fine drammatica di Navalny. Tuttavia credo sia davvero poco serio celebrarlo come eroe della libertà e della democrazia, addirittura scendendo in piazza per commemorarlo.
Questo, peraltro, mentre si fanno le pulci a veri e autentici democratici come Julian Assange, detenuti per procura dagli Stati Uniti.
Mi spiace aver fatto scaldare qualcuno, ma la vedo così.
La mia al TG Plus di Cusano Italia TV
#alexeinavalny#Navalny#JulianAssange#Assange
https://www.youtube.com/watch?v=WzArdXsyO-8&ab_channel=SavinoBalzano
На 40-й день после убийства Алексея Навального мы соберемся в Саду Анны Политковской на проспекте Комо в Милане, чтобы почтить память русского оппозиционера, который заплатил своей жизнью за решение вернуться на Родину для борьбы за другую Россию.
Присоединяйтесь, чтобы поддержать память о нем и его надеждах на Прекрасную Россию Будущего. Приносите цветы.
Встречаемся во вторник, 26 марта, в 18:30. в Милане, в саду Политковской, Corso Комо – напротив станции Гарибальди. P.S. Эта инициатива одобрена квестурой.
В Инстаграм:
https://www.instagram.com/p/C4xtUKZMmmE/?igsh=eDdqY3MwYjUzcmx3
Ассоциация Аннавива #40днейбезнавального#annaviva#alexeinavalny#alexeynavalny#40днейбезнавального#навальный
На 40-й день после убийства Алексея Навального мы соберемся в саду Vittorio Emanuele у временного мемориала.
Мы отслужим панихиду и почтим память Алексея, а также всех невинно убиенных.
Присоединяйтесь, чтобы поддержать память о нем и его надеждах на Прекрасную Россию Будущего.
Приносите цветы, плакаты.
❗L'offerta libera за служение панихиды.
❗Встречаемся во вторник, 26 марта, в 17:20. в Риме, в центре парка vittorio Emanuele, у мемориала Алексею Навальному – напротив станции Vittorio Emanuele.
P.S. Эта инициатива одобрена квестурой.
Завтра мы помянем всех невинно убиенных во время теракта в концертном зале "Крокус".
Мы помянем всех безвинно пострадавших во время этой жестокой войны.
Мы также пообщаемся и будет "открытый микрофон".
Увидимся завтра в Риме.
Link: https://www.instagram.com/p/C4xwTXvsQCL/?igsh=MWxzamhtMGNpeHNocg==
#40днейбезнавального#alexeinavalny#alexeynavalny#40днейбезнавального#навальный#алексейнавальный