Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
El Real Madrid venció 3-0 al Cádiz el día de hoy y se proclamó campeón de La Liga EA sports
Por otro lado el Girona venció 4-2 al FC Barcelona y se lograron meter en la próxima edición de la UEFA Champions League por primera vez en su historia
Felicidades a los 2 clubes👏
@Fut_planet⚜️#RealMadrid🇪🇸#Girona🇪🇸#LaLiga🇪🇸
⚽️🇪🇸Liga
Girona 1-4 Barcelona#Liga#Girona#Barcelona
Cinco partidos, cinco victorias y las dos últimas con goleada incluida. Hay líder sólido en LaLiga y parece que para rato. Este Barça de Hansi Flick empieza a meter miedo a sus rivales con un juego muy bonito de ver en el que hay que destacar su mejoría en defensa, su pegada en ataque y una presión para recuperar balón que empieza recordar a la que le llevó a los títulos en la época de Messi.
https://www.marca.com/futbol/primera-division/cronica/2024/09/15/66e6b26122601d7d588b457f.html
🏆@Info288_deportes
⚽️🇪🇸Liga
Atlético 3-0 Girona#Liga#Atlético#Girona
Atlético de Madrid estrenó este domingo su casillero de victorias en LaLiga EA Sports 2024-2025 después de imponerse con autoridad por 3-0 al Girona FC en el Estadio Cívitas Metropolitano, un partido en el que los rojiblancos fueron superiores ante un rival un tanto inocente.
https://www.europapress.es/deportes/futbol-00162/noticia-atletico-brinda-noche-solida-metropolitano-20240825233757.html
🏆@Info288_deportes
⚽️🇪🇸Liga
Girona 2-1 Athletic#Liga#Girona#Athletic
Los mediodías de otoño con sol son de agradecer. Que se lo digan a Gazzaniga, que se fue del partido con tres penaltis detenidos a Berenguer, Iñaki Williams y Herrera. Pulido Santana pitó tres penaltis por recomendación del VAR, ya que no había visto ninguna de las acciones, que fueron sancionables a la vez que evitables. Tampoco estuvo fino para advertir que en el segundo Gazzaniga se adelantó y tuvo que repetirse. El argentino ni se inmutó. Si le tiran seis, los seguiría parando. En el otro área, a un paso del final, Padilla no pudo detener el lanzamiento de Stuani.
https://www.marca.com/futbol/primera-division/cronica/2024/10/06/67028ae0e2704e531e8b45a5.html
🏆@Info288_deportes
⚽️🇪🇸Liga
Girona 0-1 Real Sociedad#Liga#Girona#RealSociedad
La Real Sociedad volvió del parón con una buena victoria, firmada con un gol de Mikel Oyarzabal, en un partido en el que los txuriurdin pudieron haber marcado algún tanto más, pero tras no hacerlo terminaron sufriendo frente a un Girona que acusó las bajas.
https://www.marca.com/futbol/primera-division/cronica/2024/10/19/6713c6c5e2704e63b98b4592.html
🏆@Info288_deportes
⚽️🇪🇸 Liga
Valencia 2-0 Girona#Liga#Valencia#Girona
No importa lo profunda que sea la crisis o la salvajada que cometa Peter Lim, el Valencia siempre podrá contar con Mestalla para salir del agujero. El cuadro de Baraja ha sumado su primer triunfo del curso ante el Girona y ya no es el colista de Primera división. 13 partidos y 159 días ha necesitado el Valencia para volver a sumar de tres y volver a respirar tras un comienzo de Liga terrible que ha encendido todas la alarmas, pero no ha impedido que más de 40.000 fieles se citen en su coliseo para reanimar a su equipo.
https://www.marca.com/futbol/primera-division/cronica/2024/09/21/66ee7c6546163f58708b45a4.html
🏆@Info288_deportes
⚽️🇪🇸Liga
Getafe 0-1 Girona#Liga#Getafe#Girona
El Girona tumbó la muralla del Coliseum por primera vez esta temporada gracias a un gol de Yangel Herrera en la única ocasión de los de Míchel en un encuentro en el que los suyos tuvieron que jugar 'a otra cosa' y sufrir de lo lindo para llevarse la victoria. Los de Bordalás, de nuevo con problemas mayúsculos para general peligro real, siguen bordeando el descenso y se marchan muy tocados a la ventana de selecciones.
https://www.marca.com/futbol/primera-division/cronica/2024/11/10/6730df79268e3ee1418b4578.html
🏆@Info288_deportes