Регулярно требуется преобразовать какой-либо текст в максимально совместимый текст для 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
Stanno per iniziare le Next Gen Finals ATP: la prima impressione, almeno personalmente, è che si apra così la nuova stagione, ma in realtà è l’ultimo atto di quella in corso.
Tastiamo il polso della situazione su interesse/tifo/etc prima che parta la giostra 🤪
[seguono #sondaggi]
#Sondaggi#Italia
Sondaggio di EMG:
"Lei è d'accordo che l’Italia invii armi all'Ucraina?"
No: 54% (+5)
Sì: 30% (-5)
Non so: 16%
Data rilevazione: 10 maggio
+/-: 29 marzo
Intervistati: 1485
In foto il quesito tra elettori dei partiti.
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di EMG:
"Secondo lei l’Europa dovrebbe rivendicare, nel conflitto, una maggiore autonomia rispetto agli Stati Uniti?"
Sì: 62%
No: 21%
Non so: 17%
Data rilevazione: 10 maggio
Intervistati: 1485
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di SWG:
"Lei è in accordo o in disaccordo con il fatto che l'Italia invii armi ai combattenti ucraini?"
Disaccordo: 46%
D'accordo: 43%
Non so: 11%
"Per chi ha votato 'in disaccordo': quali sono i suoi motivi della contrarietà all'invio di armi?"
Non è giusto perché prolunga la guerra: 24%
Sono preoccupato/a che con l'invio di armi l'Italia rischi ritorsioni da parte della Russia: 16%
L'Italia non dovrebbe fare nulla, se la sbrighino tra loro: 6%
Data rilevazione: 27 aprile-2 maggio
Intervistati: 1200
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di Index:
"Lei è favorevole o contrario all'invio di armi all'Ucraina?"
Contrario: 44%
Favorevole: 36,5%
Non so: 20%
Data rilevazione: 27 aprile
Intervistati: 800
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di Ipsos:
Sei favorevole al referendum sulla abolizione della legge Severino?
No: 26%
Sì: 20%
Non so: 54%
Intervistati: 1000
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di Ipsos:
Sei favorevole al referendum sulla limitazione alla custodia cautelare?
No: 26%
Sì: 17%
Non so: 57%
Intervistati: 1000
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di Ipsos:
Sei favorevole al referendum sulla separazione delle carriere?
Sì: 36%
No: 10%
Non so: 54%
Intervistati: 1000
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di Ipsos:
Sei favorevole al referendum sull'equa valutazione dei magistrati?
Sì: 28%
No: 12%
Non so: 60%
Intervistati: 1000
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di Ipsos:
Sei favorevole al referendum sulle candidature al CSM?
Sì: 23%
No: 11%
Non so: 66%
Intervistati: 1000
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di BiDiMedia:
"Se l'embargo totale del gas e petrolio russi avesse il costo di dover razionare l'utilizzo dell'energia nei prossimi mesi, lei sarebbe ancora favorevole?"
Molto/Abbastanza: 46%
Poco/Per nulla: 44%
Non so: 10%
Data rilevazione: 7-9 aprile
Intervistati: 3570
In foto il quesito tra elettori dei partiti.
@UltimoraPolitics
#Sondaggi#Italia
Sondaggio di BiDiMedia:
"Lei è favorevole ad un embargo totale del gas e petrolio russi?"
Molto/Abbastanza: 50%
Poco/Per nulla: 42%
Non so: 8%
Data rilevazione: 7-9 aprile
Intervistati: 3570
In foto il quesito tra elettori dei partiti.
@UltimoraPolitics