Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
Getting excited over the 6.6 sales? Ask yourself if you really need the item before adding it to your cart!
Consider using or repairing what you have, instead of replacing it. #ReduceReuseRecycle
Check out some tips here: https://www.youtube.com/playlist?list=PLPX9rYUbMZF3GLoLkP2Bxd0TelSHylBOu
It can be very tempting to do online shopping this circuit breaker period, but think about whether you really need it before you put it in your cart! #ReduceReuseRecycle
Dressing up as your favourite superhero this Halloween?
Get creative and make a costume using everyday household items. When you’re done, recycle or reuse what you can of your outfit, so that your superhero legacy will continue to live on 🦸♂️
#3Rs#ReduceReuseRecycle
Be a green champion by refusing disposable plastic bags and using a reusable bag. Marvel at the environmental gains you achieve on a daily basis 💪#3Rs#ReduceReuseRecycle
✨ Like training dragons, recycling right takes practice. Master these 3 moves to #RecycleRight: Empty ➡️ Rinse ➡️ Dry
♻️www.nea.gov.sg/3R#3Rs#ReduceReuseRecycle#TowardsZeroWaste#SustainableSG
60 years of progress, but what’s next for Singapore?
Higher temperatures, more wet and dry extremes, and accelerating increase in mean sea levels are projected. In the worst-case scenario, the 𝗺𝗲𝗮𝗻 𝘀𝗲𝗮 𝗹𝗲𝘃𝗲𝗹 around Singapore is projected to 𝗿𝗶𝘀𝗲 𝗯𝘆 𝟭.𝟭𝟱𝗺 𝗯𝘆 𝘁𝗵𝗲 𝗲𝗻𝗱 𝗼𝗳 𝘁𝗵𝗲 𝗰𝗲𝗻𝘁𝘂𝗿𝘆, and up to 𝗮𝗿𝗼𝘂𝗻𝗱 𝟮𝗺 𝗯𝘆 𝟮𝟭𝟱𝟬.
Let’s commit to a sustainable future by taking climate actions to reduce our waste and carbon footprint. #3Rs#ReduceReuseRecycle#SG60
Happy 60th National Day, Singapore! 🇸🇬
As we celebrate our progress as a nation, let’s also commit to building a #SustainableSG for present and future generations. Let’s reduce our carbon footprint by taking climate actions such as adopting energy-saving and #ReduceReuseRecycle habits.
#SG60#KeepSGClean
#ProTip: There’s no need to sort your recyclables! Paper, plastic, glass, and metal can all be placed in the recycling bins ♻️✌️
But do remember to CHECK and CLEAN before you RECYCLE: www.go.gov.sg/recycleright
#RecycleRight#ReduceReuseRecycle
Give your home a refreshed look that brings renewed fortune to every corner.
Revamp your space by rearranging your furniture or upcycling your Lunar New Year decorations.
#3Rs#ReduceReuseRecycle#SustainableSG#TowardsZeroWaste#LunarNewYear2024
Switch off for #EarthHour at 8:30pm!
But let's not stop there. Let this yearly reminder inspire us to continue making sustainable choices. Your everyday choices matter more than you might think!
Small steps such as adopting energy-saving habits and recycling right can make a difference. Imagine these small acts being amplified by millions worldwide. 🌍💚
#EnergyEfficiency#ReduceReuseRecycle#RecycleRight
Building climate resilience will keep Singapore steady pom pi pi for the next 60 years! 💃🕺
Let’s take action for a #SustainableSG by adopting energy-saving and #ReduceReuseRecycle habits.
#SG60#ClimateActionSG
Tidying up your house over the weekend?
Here’s a #SustainabilityHack to keep your table free of messy wires! You can also beautify this DIY cable organiser to match your room design.
#3Rs#ReduceReuseRecycle#SustainableSG