Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
A map of the Israeli Airstrikes on the Lebanese Beqaa region that took the lives of 63 civilians and i jured more than 100 people in a raid of more than 100 airstrikes targeting the region.
#LebanonUnderAttack
Genocidal Psychopaths of the Zionist Israeli terrorist army blow up the entire Lebanese bordering Village of Mhaybeeb this morning on October 16, 2024.
#LebanonUnderAttack
#Israel carried out a large-scale massacre today, November 1, 2024, in the Lebanese towns of Baalbek district. 52 people were killed, 72 wounded, and 9 remain missing after 25 airstrikes by Israeli warplanes conducted over two hours, from 2 p.m. to 4 p.m.
#LebanonUnderAttack
Even in the darkest times of #war, humor becomes a tool for resilience, offering brief moments of relief and a way to cope with the harsh realities. It’s a reminder that laughter, no matter how fleeting, can be a powerful act of defiance and hope in the face of adversity.
#LebanonUnderAttack
The Lebanese Ministry of Health's Emergency Operations Center reported that the death toll from the Israeli assault has climbed to 2,653, with 12,360 others wounded since October 8, 2023. This staggering rise reflects the continuous bombardment and escalating violence.
#Israel#Lebanon#LebanonUnderAttack
#Hezbollah carried out a series of coordinated rocket and drone attacks, targeting Israeli military sites, gatherings, and settlements. The operations resulted in casualties and showcased the group's ongoing military capabilities.
#LebanonUnderAttack#Israel
#Israel conducted heavy airstrikes overnight in #Beirut suburbs on the Mreijeh area taking out an entire neighborhood turning it to rubble.
#LebanonUnderAttack
Israel has struck Beirut once again, this time targeting Mar Elias Street; the heart of the capital and one of its most densely populated areas during the war, as countless displaced families from the suburbs have sought refuge there.
This relentless aggression is not just an attack on civilians; it’s a blatant violation of all norms of international law, crossing every red line.
#LebanonUnderAttack
#BeirutUnderAttack
Zionist Israeli Psychopaths hit a home in Ayto town in #Zgharta north #Lebanon that was housing families displaced from South Lebanon and Beirut suburbs. 25 humans in the house, the Red cross so far said that 18 are martyred.
I will not share any videos or photos, as many of the women might be hijabis, and the footage shows them in heartbreaking scenes without their hijabs.
#LebanonUnderAttack
Devastation in the heart of Beirut: On the night of November 17, #Israel targeted a densely populated building on the famous Mar Elias Street, setting off a massive fire that raged through the night. The building housed motor generators and an electronics shop, where lithium batteries likely fueled the inferno, adding to the chaos and destruction.
#LebanonUnderAttack#WarCrimes#Beirut
Ophthalmologist MP Elias Jradeh reveals that a blockade was imposed on Lebanon regarding the import of corneas after the Pagers bombing, which led to their disappearance from the local market and harmed various Lebanese citizens.
#Lebanon#PagersAttack#Hezbollah#LebanonUnderAttack
In a heartbreaking video, Julia shared moments while she was playing the piano in her home in Khiam, South Lebanon, which she discovered in a video circulated by Israeli soldiers that was destroyed during the border clashes when they were attempting to occupy her town.
#SouthLebanon#Khiam#LebanonUnderAttack#Israel