Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
🌎 The rare blue mineral painite was first discovered in Myanmar in 1951 and is so scarce that only a few hundred crystals have ever been found worldwide. Painite contains boron, zirconium, and aluminum, and transparent gem-quality stones are especially valuable to collectors. ✨
#geology⚡#minerals⚡#gemstones
👉subscribe Interesting Planet
👉more Channels
🌎 Red beryl, also called bixbite, is one of the rarest gemstones on Earth and is found almost exclusively in Utah’s Wah Wah Mountains. Its rich red color comes from trace amounts of manganese. Fewer than one red beryl is found for every 150,000 diamonds mined worldwide. ✨
#minerals⚡#gemstones⚡#geology
👉subscribe Interesting Planet
👉more Channels
🌎 Discovered only in Greenland and the Kola Peninsula, rare mineral serendibite forms deep in metamorphic rocks and can display vivid blue-green hues. Gem-quality serendibite is so scarce that a single carat can cost over $2,000. ✨
#minerals⚡#geology⚡#gemstones
👉subscribe Interesting Planet
👉more Channels
🌎 Blue garnet is one of the rarest gemstones on Earth, discovered in Madagascar in the late 1990s. Unlike most garnets, it changes color—from blue-green in daylight to purple-red under incandescent light—due to trace amounts of vanadium absorbing light differently. Only tiny amounts have been found so far, with most crystals under one carat. ✨
#geology⚡#minerals⚡#gemstones
👉subscribe Interesting Planet
👉more Channels
🌎 One of the rarest crystals on Earth is musgravite, first discovered in Australia’s Musgrave Ranges in 1967. Transparent musgravite gemstones are extremely scarce, with fewer than 20 certified specimens reported worldwide. ✨
#minerals⚡#gemstones⚡#geology
👉subscribe Interesting Planet
👉more Channels
🌎 The mineral grandidierite is one of the world’s rarest gemstones and was first discovered in Madagascar in 1902. Its blue-green crystals get their striking color from traces of iron, and transparent gem-quality stones are so scarce that most museums only display tiny specimens. ✨
#minerals⚡#gemstones⚡#geology
👉subscribe Interesting Planet
🌎 The mineral taaffeite was discovered accidentally in 1945 by gemologist Richard Taaffe, who bought a mislabeled gemstone in Dublin. This rare crystal is prized for its lavender color and is mostly found in Sri Lanka, Myanmar, and Madagascar. Fewer than 50 verified cut taaffeites exist worldwide. ✨
#minerals⚡#gemstones⚡#geology
👉subscribe Interesting Planet
🌎 An ancient “rainbow” mineral called ammolite forms from fossilized ammonite shells. With its dazzling reds, greens, and blues, ammolite is one of the world’s rarest gemstones, found mainly in Canada’s Rocky Mountains. ✨
#geology⚡#fossils⚡#gemstones
👉subscribe Interesting Planet
🌎 In Australia’s opal fields, some opals contain ancient fossilized bones or shells, perfectly preserved in dazzling rainbow stone. This rare “opalized fossil” forms as minerals slowly replace bone, creating a sparkling record of prehistoric life. ✨
#fossils⚡#minerals⚡#gemstones
👉subscribe Interesting Planet
🌎 The mineral jeremejevite forms pale blue, yellow, or colorless crystals and is among the world’s rarest minerals. Discovered in Namibia in 1883, it is an aluminum borate mineral that forms in granite pegmatites. Transparent gem-quality jeremejevite is so scarce that it can sell for over $2,000 per carat. ✨
#minerals⚡#crystals⚡#gemstones
👉subscribe Interesting Planet
🌎 Alexandrite is a rare mineral that changes color under different lighting—appearing green in daylight and red under incandescent light. This gemstone was first discovered in Russia’s Ural Mountains in 1830, and crystals large enough for jewelry are extremely scarce worldwide. ✨
#alexandrite⚡#minerals⚡#gemstones
👉subscribe Interesting Planet
👉more Channels