Я ищу лучший способ "слагать" строку, что такое "слаг" , и мое текущее решение основано на этом рецепте
Я немного изменил его на:
s = 'String to slugify'
slug = unicodedata.normalize('NFKD', s)
slug = slug.encode('ascii', 'ignore').lower()
slug = re.sub(r'[^a-z0-9]+', '-', slug).strip('-')
slug = re.sub(r'[-]+', '-', slug)
Кто-нибудь видит какие-либо проблемы с этим кодом? Он работает нормально, но, может быть, я что-то упускаю или знаете способ получше?
Ответы:
Существует пакет python с именем
python-slugify
, который довольно хорошо справляется с заменой:Работает так:
from slugify import slugify txt = "This is a test ---" r = slugify(txt) self.assertEquals(r, "this-is-a-test") txt = "This -- is a ## test ---" r = slugify(txt) self.assertEquals(r, "this-is-a-test") txt = 'C\'est déjà l\'été.' r = slugify(txt) self.assertEquals(r, "cest-deja-lete") txt = 'Nín hǎo. Wǒ shì zhōng guó rén' r = slugify(txt) self.assertEquals(r, "nin-hao-wo-shi-zhong-guo-ren") txt = 'Компьютер' r = slugify(txt) self.assertEquals(r, "kompiuter") txt = 'jaja---lol-méméméoo--a' r = slugify(txt) self.assertEquals(r, "jaja-lol-mememeoo-a")
Посмотреть больше примеров
Этот пакет делает немного больше, чем то, что вы опубликовали (взгляните на исходный код, это всего лишь один файл). Проект все еще активен (обновлен за 2 дня до моего первоначального ответа, более семи лет спустя (последний раз проверено 30 июня 2020 г.), он все еще обновляется).
осторожно : есть второй пакет с именем
slugify
. Если у вас есть оба из них, вы можете столкнуться с проблемой, поскольку они имеют одинаковое имя для импорта. Тот, что только что названslugify
, не сделал все, что я проверил:"Ich heiße"
стал"ich-heie"
(должен быть"ich-heisse"
), поэтому обязательно выберите правильный при использованииpip
илиeasy_install
.источник
python-slugify
под лицензией MIT, но использует то,Unidecode
что под лицензией GPL, поэтому может не подходить для некоторых проектов.python-slugify
теперь по умолчанию использует Artistic License'd,text-unidecode
а не GPL-лицензиюUnidecode
, что позволяет решить вашу проблему лицензирования. github.com/un33k/python-slugify/commit/…Установите форму unidecode отсюда для поддержки Unicode
# -*- coding: utf-8 -*- import re import unidecode def slugify(text): text = unidecode.unidecode(text).lower() return re.sub(r'[\W_]+', '-', text) text = u"My custom хелло ворлд" print slugify(text)
источник
slugify("My custom хелло ворлд")
наslugify(u"My custom хелло ворлд")
, и он должен работать.str
. Это скрывает встроенныйstr
тип.Существует пакет python с именем awesome-slugify :
Работает так:
from slugify import slugify slugify('one kožušček') # one-kozuscek
awesome-slugify страница github
источник
slugify(text).lower()
если вы этого хотите.Он хорошо работает в Django , поэтому я не понимаю, почему это не будет хорошей функцией slugify общего назначения.
У вас с этим проблемы?
источник
from django.utils.text import slugify
Проблема в строке нормализации ascii:
slug = unicodedata.normalize('NFKD', s)
Это называется нормализацией Unicode, которая не разбивает множество символов на ascii. Например, он удалит символы, отличные от ascii, из следующих строк:
Лучший способ сделать это - использовать модуль unidecode, который пытается транслитерировать строки в ascii. Итак, если вы замените указанную выше строку на:
import unidecode slug = unidecode.unidecode(s)
Вы получите лучшие результаты для указанных выше строк, а также для многих греческих и русских символов:
источник
def slugify(value): """ Converts to lowercase, removes non-word characters (alphanumerics and underscores) and converts spaces to hyphens. Also strips leading and trailing whitespace. """ value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') value = re.sub('[^\w\s-]', '', value).strip().lower() return mark_safe(re.sub('[-\s]+', '-', value)) slugify = allow_lazy(slugify, six.text_type)
Это функция slugify, присутствующая в django.utils.text. Этого должно хватить на ваши требования.
источник
Unidecode хорош; однако будьте осторожны: unidecode - это GPL. Если эта лицензия не подходит, используйте эту
источник
Пара вариантов на GitHub:
Каждый из них поддерживает несколько разные параметры для своего API, поэтому вам нужно просмотреть их, чтобы понять, что вы предпочитаете.
В частности, обратите внимание на различные варианты, которые они предоставляют для работы с символами, отличными от ASCII. Pydanny написал очень полезное сообщение в блоге, иллюстрирующее некоторые различия в обработке Unicode в этих slugify-библиотеках: http://www.pydanny.com/awesome-slugify-human-readable-url-slugs-from-any-string.html Это сообщение в блоге немного устарело, потому что Mozilla
unicode-slugify
больше не зависит от Django.Также обратите внимание, что в настоящее время
awesome-slugify
действует GPLv3, хотя есть открытая проблема, когда автор говорит, что предпочел бы выпускать как MIT / BSD, просто не уверен в законности: https://github.com/dimka665/awesome-slugify/issues/ 24источник
Вы можете изменить последнюю строку на
slug=re.sub(r'--+',r'-',slug)
так как шаблон
[-]+
ничем не отличается от-+
, и вы действительно не заботитесь о сопоставлении только одного дефиса, только двух или более.Но, конечно, это совсем мелочь.
источник
Другой вариант есть
boltons.strutils.slugify
. Boltons имеет ряд других полезных функций и распространяется поBSD
лицензии.источник