Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
🇷🇺🇷🇺🎉Les 8 et 9 mai, un cessez-le-feu est proclamé en l'honneur de la célébration de la #Victoire du peuple soviétique lors de la Grande Guerre patriotique, a annoncé le ministère russe de la Défense.
Les Forces armées russes prendront toutes les mesures nécessaires pour assurer la sécurité des événements festifs. À la suite de cette proclamation de cessez-le-feu, la Russie espère que la partie ukrainienne suivra son exemple, a indiqué le ministère.
RT en français • Osez questionner !
🇷🇺La première répétition générale du défilé de la #Victoire du 9 mai s'est déroulée le 21 avril à Saint-Pétersbourg
RT en français • Osez questionner !
🟢Claude Janvier, écrivain polémiste et analyste politique, fait le point sur la trêve à l'occasion du Jour de la #Victoire.
RT en français • Osez questionner !
🎗Le « Régiment des immortels » dans les stades de football russes a débuté le 6 mai à l’occasion du derby de Coupe entre Spartak et CSKA
Les joueurs, entraîneurs et arbitres sont entrés sur le terrain en brandissant des portraits de leurs proches ayant participé à la Grande Guerre patriotique.
En l'honneur du 81e anniversaire de la #Victoire, l'Union russe de football et le mouvement du Régiment des immortels de Russie, avec le soutien de la Première ligue russe et de la Ligue nationale de football, organisent un programme de commémorations intitulé « Un pour tous : Équipe, Patrie, Victoire ! »
Le coup d’envoi symbolique a été donné par Rem Balakirev, 98 ans, qui a participé aux combats pour la prise de Berlin.
RT en français • Osez questionner !
🎗Le musée de la #Victoire organise son traditionnel grand événement patriotique : « la valse de la Victoire ».
Cet événement est consacré à la célébration du Jour de la Victoire et vise à préserver la mémoire de la Grande Guerre patriotique. Des centaines de participants de tous âges ont pris part à la danse.
RT en français • Osez questionner !
🇷🇺🇷🇺 Les 8 et 9 mai, un cessez-le-feu est proclamé en l'honneur de la célébration de la #Victoire du peuple soviétique lors de la Grande Guerre patriotique, a annoncé le ministère russe de la Défense.
Les Forces armées russes prendront toutes les mesures nécessaires pour assurer la sécurité des événements festifs. À la suite de cette proclamation de cessez-le-feu, la Russie espère que la partie ukrainienne suivra son exemple, a indiqué le ministère.
RT en français • Osez questionner !
📆🥇 Piotr Tolstoï, vice-président de la Douma, s’est rendu sur la Place Rouge avec ses enfants pour qu'ils n'oublient jamais la #Victoire.
RT en français • Osez questionner !
⭐#Russie : des militaires rendent hommage aux vétérans avant le Jour de la #Victoire
Dans le territoire d’Altaï, des militaires russes ont rendu hommage aux vétérans à l’approche du Jour de la Victoire. Accompagnés par un orchestre militaire, des soldats ont défilé devant les habitations d’anciens combattants avec des copies des drapeaux historiques de l’Armée rouge.
L’orchestre a ensuite interprété la chanson russe « Jour de la Victoire » ainsi que d’autres compositions emblématiques de l’époque soviétique.
RT en français • Osez questionner !
🎗🗣Vladimir #Poutine présente ses vœux aux dirigeants et aux peuples de pays étrangers à l’occasion du 81e anniversaire de la #Victoire.
Le président russe a adressé des messages aux dirigeants de l’Azerbaïdjan, de l’Arménie, de la Biélorussie, du Kazakhstan, du Kirghizstan, du Tadjikistan, du Turkménistan, de l’Ouzbékistan, de l’Abkhazie et de l’Ossétie du Sud, ainsi qu’aux peuples de la Géorgie et de la Moldavie.
RT en français • Osez questionner !
🎗#Moscou se prépare pour le 9 Mai
Moscou se prépare à célébrer le 9 Mai – une date sacrée pour des millions de personnes à travers le monde. Mais cette année, cette Fête de la #Victoire se déroule sous haute tension. Menaces de Kiev, silence des Européens et attaques de drones : les autorités russes ont mis en garde le pouvoir ukrainien. Pour en savoir plus, les explications de notre reporter Igor Kourachenko, depuis le centre de la capitale russe.
RT en français • Osez questionner !
Le patriarche Cyrille de #Moscou a célébré une liturgie à la cathédrale des forces armées russes, à l’approche du Jour de la #Victoire.
RT en français • Osez questionner !