Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
This World Environment Day, let’s do our part to #BeatPlasticPollution together.
Simply bring along reusable bags and containers wherever you go to reduce your reliance on disposables. Let’s #ChooseReusables and work #TowardsZeroWaste together!
Check out some tips here: https://www.youtube.com/playlist?list=PLPX9rYUbMZF2Ofk62WvXxsv0vXR6Sh6CU
🌳🏃🏻♂️ Плоггинг — уникальное событие, объединяющее бег и заботу об окружающей среде! Присоединяйтесь 4 июня и помогите сохранить чистоту нашего города! Все собранные материалы будут переданы на переработку.
🏃♂️ Участие бесплатное! Собравшие больше всех пластика получит призы:
1️⃣ место — 3 000 000 сумов
2️⃣ место — 2 000 000 сумов
3️⃣ место — 1 000 000 сумов.
💚 Как принять участие?
• Зарегистрируйтесь
• Пробегите или пройдите любое расстояние до пункта приема, собирая мусор вдоль пути.
• После сдачи собранного мусора и публикации ваших достижений в социальных сетях вы получите футболку, шопер и кепку.
• Вы можете начать своё движение с пункта приема мусора, и тогда вас обеспечат перчатками и мусорными пакетами.
📸 Делитесь фотографиями в соцсетях с хештегами #beatplasticpollution#бойзагрязнениюпластиком, отмечайте организатора @ecogov.uz и партнёров @cocacola_uzbekistan, @prorun.uz
📍 Место и ⏰ приема: Центральный экопарк Ташкента имени Бабура с 7:00 до 20:00.
♻️5 июня — Всемирный день окружающей среды
Каждый год в мире производится более 400 миллионов тонн пластика, при этом половина из него предназначена для одноразового использования. К сожалению, перерабатывается менее 10%. Ежегодно около 11 миллионов тонн пластика попадает в водоёмы — это эквивалентно весу 2 200 Эйфелевых башен.
🧬 Микропластик — частицы размером менее 5 мм — проникает в пищу, воду и воздух. По оценкам, каждый человек ежегодно непроизвольно потребляет более 50 000 таких частиц, и ещё больше — при вдыхании.
🗻 Пластиковое загрязнение угрожает не только здоровью человека, но и всей экосистеме планеты — от горных вершин до морского дна.
🌍 В этом году Всемирный день окружающей среды проходит под девизом #BeatPlasticPollution. Цель — напомнить о нашей общей ответственности в борьбе с пластиковым кризисом, внедрить предлагаемые решения и двигаться к устойчивому будущему.
⏳ Времени почти не осталось. Если не начать действовать сегодня, завтра может быть уже поздно. Изменение климата и экологический кризис требуют срочных мер.
📣 Откажитесь, уменьшите, используйте повторно, переработайте и переосмыслите. Каждый маленький шаг имеет значение и приближает нас к большим переменам.
#WorldEnvironmentDay#GenerationRestoration
♻️5-iyun – Butunjahon atrof-muhit kuni
Hozirda dunyo bo‘yicha har yili 400 million tonnadan ortiq plastik ishlab chiqariladi. Shuning yarmi faqat bir marta foydalanish uchun mo‘ljallangan. Afsuski, ulardan atigi 10 foizigina qayta ishlanadi. Har yili 11 million tonna plastik suv havzalariga tushadi — bu 2 200 ta Eyfel minorasining og‘irligiga teng.
🧬 Mikroplastikalar — 5 mm dan kichik zarrachalar — ovqat, suv va havoga aralashib, har bir inson tanasiga yiliga o‘rtacha 50 000 dona plastik zarracha kirishiga sabab bo‘lmoqda.
🗻 Plastik ifloslanishi nafaqat inson salomatligi, balki butun sayyoramizdagi ekotizimlarga tahdid solmoqda — tog‘lar cho‘qqisidan to okean tubigacha.
🌍 Bu yilgi Atrof-muhit kuni #BeatPlasticPollution shiori ostida o‘tkazilmoqda. Maqsad — plastikka qarshi kurashda har birimizning mas’uliyatimiz borligini eslatish, taklif etilgan yechimlarni keng joriy etish va barqaror kelajak sari harakat qilish.
⏳ Vaqt juda kam. Iqlim o‘zgarishi va atrof-muhit inqiroziga qarshi kurashni bugunoq boshlamasak, ertaga kech bo‘lishi mumkin.
📣 Siz ham rad eting, kamaytiring, qayta foydalaning, qayta ishlang va qayta o‘ylang. Har bir kichik qadam katta o‘zgarishlarga olib keladi.
#WorldEnvironmentDay#GenerationRestoration