Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
🌍 Asia is the largest continent, but the Pacific Ocean is even bigger—its area almost doubles that of all land in Asia, making it Earth’s vastest single geographic feature. ✨
#continents⚡#oceans⚡#earth⚡#geography⚡#nature
👉subscribe Amazing Geography
👉more Channels
🌍 The Pacific Ocean is wider than the entire Moon. At its widest, it stretches over 19,000 kilometers from Asia to the Americas—more than the Moon’s diameter of 3,474 kilometers. ✨
#continents⚡#oceans⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography
👉more Channels
🌍 The boundary between Europe and Asia runs mostly along the Ural Mountains and Ural River. This dividing line is not marked by ocean or sea, making it the only major continental border mostly on land. ✨
#continents⚡#borders⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography
👉more Channels
🌍 Africa is the only continent that stretches from the northern temperate zone all the way to the southern temperate zone, crossing both the Equator and the prime meridian. ✨
#continents⚡#Africa⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography🌍
🌍 The Atlantic Ocean is expanding as the Americas move away from Europe and Africa. This slow drift adds about 2.5 centimeters of new seafloor every year along the Mid-Atlantic Ridge. ✨
#continents⚡#ocean⚡#geology⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography
👉more Channels
🌍 The Mid-Atlantic Ridge runs down the center of the Atlantic Ocean, forming the world’s longest mountain chain—most of it hidden beneath the sea between continents. ✨
#continents⚡#ocean⚡#geology⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography
👉more Channels
🌍 The Southern Ocean, officially recognized in 2021, surrounds Antarctica and connects the Atlantic, Pacific, and Indian Oceans, forming a unique ring of cold currents that help regulate Earth’s climate. ✨
#continents⚡#oceans⚡#climate⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography🌍
🌍 The Atlantic Ocean is growing wider each year as the Americas slowly drift apart from Europe and Africa, adding about 2.5 centimeters annually—roughly the speed fingernails grow. ✨
#continents⚡#oceans⚡#tectonics⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography
👉more Channels
🌍 The Eurasian and North American continents are moving apart by about 2.5 centimeters every year along the Mid-Atlantic Ridge, slowly widening the Atlantic Ocean over millions of years. ✨
#continents⚡#oceans⚡#tectonics⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography
👉more Channels
🌍 Antarctica is the only continent entirely surrounded by ocean and is nearly twice the size of Australia. Its thick ice reflects sunlight, helping regulate Earth’s overall temperature. ✨
#continents⚡#oceans⚡#Antarctica⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography
👉more Channels
🌍 In prehistoric times, people migrated out of Africa in waves, eventually reaching every continent except Antarctica. This journey took tens of thousands of years and shaped human diversity. ✨
#migration⚡#history⚡#continents⚡#geography⚡#nature⚡#earth
👉subscribe Amazing Geography🌍