Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
¡¡¡LA FIEBRE AMARILLA HA VUELTO!!!
▪️ Habrá dos cabezas de serie Nº7/Nº8 (Lakers en el oeste y Miami en el este) en las finales de conferencia de una misma temporada por PRIMERA VEZ en TODA la historia de la #NBA.
▪️ Lakers es el SEGUNDO equipo del oeste que llega a las finales… https://t.co/BBQT90Jnivhttps://t.co/26DgtEcEl5
SAC 100-120 GSW (FT)
▪️ Golden State Warriors es el primer vigente campeón en TODA la historia de la #NBA que supera la primera ronda de los playoffs ganando un séptimo partido fuera de casa.
▪️ Los Warriors han ganado un séptimo partido fuera de casa por TERCERA vez en su… https://t.co/pUhVvpterC
Temporadas en las que Detroit Pistons fue el peor equipo de la #NBA 1965-66 (tardaron 23 años en volver a ser campeones) 1979-80 (tardaron 9 años en volver a ser campeones) 2022-23 Temporadas en las que San Antonio Spurs fue el peor equipo del oeste: 2022-23
🏀🇺🇸NBA
El épico nepotismo de LeBron James marca el inicio de la NBA#NBA
La NBA comienza en la madrugada del miércoles (hora española) y ya son toneladas de tinta las que han corrido en las últimas semanas sobre la mejor liga de baloncesto del mundo. Son los Boston Celtics, actuales campeones y equipo más laureado de la competición con 18 anillos, los principales protagonistas de la temporada 2024-25 por su favoritismo para repetir éxito. También los New York Knicks, que tras fichar al ala pívot Karl Anthony Towns pretenden romper la maldición de 51 años sin hacerse con la corona. Incluso los Dallas Mavericks de Luka Doncic levantan extensa expectación después de llegar a las finales de la última edición y haber adquirido a Klay Thompson, uno de los emblemas de la última dinastía de la competición, los Golden State Warriors.
LeBron James será el primer jugador de la historia de la liga en compartir vestuario con su hijo, Bronny James. La estrella de Los Angeles Lakers, tras ganar cinco anillos con cuatro equipos diferentes (dos con los Miami Heat, uno con los Cleveland Cavaliers y el último con los Lakers), buscaba un último desafío legendario, la última frontera. Y dado que tuvo al primero de sus retoños con tan solo 19 años (ahora tiene 39), optó por el nepotismo.
Una realidad que se consumó el pasado julio, cuando el jefe del clan James prolongó su relación con los californianos dos años a cambio de más de 100 millones de dólares y, a cambio, los Lakers seleccionaron en el Draft a su hijo en la posición 55, cifra reservada a jugadores a los que no se les intuye un sólido recorrido en la NBA. El aquelarre era una realidad, padre e hijo compartirían vestuario y jugarían en uno de los equipos más icónicos de la historia del baloncesto.
En uno de los primeros partidos de Bronny James con los Lakers en la liga de verano, competición de pura pretemporada en la que ni siquiera están presentes los mejores jugadores de cada franquicia, las cámaras captaron a Jaylen Brown, estrella de los Celtics, confesar lo siguiente: «No creo que Bronny tenga nivel para ser un profesional». Pidió disculpas el MVP de las últimas finales de la NBA, pero lo cierto es que el de Georgia abrió la veda de los ataques hacia el joven Bronny.
https://www.abc.es/deportes/baloncesto/epico-nepotismo-lebron-james-marca-inicio-nba-20241021042251-nt.html
🏆@Info288_deportes