Stug slugification в Python
Я ищу лучший способ "slugify" string что "slug" - это, а мое текущее решение основано на этот рецепт
Я немного изменил его:
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)
Кто-нибудь видит какие-либо проблемы с этим кодом? Он работает нормально, но, может быть, я что-то упустил или вы знаете лучший способ?
Ответы
Ответ 1
Существует пакет python с именем python-slugify
, который выполняет довольно неплохую работу:
pip install 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 дня до моего ответа, более четырех лет спустя (последний раз проверен 2017-04-26), он по-прежнему обновляется).
осторожно. Рядом с ним находится второй пакет, названный slugify
. Если у вас есть оба из них, у вас может возникнуть проблема, так как они имеют одинаковое имя для импорта. Тот, который только что назвал slugify
, не сделал все, что я быстро проверил: "Ich heiße"
стал "ich-heie"
(должен быть "ich-heisse"
), поэтому не забудьте выбрать правильный, при использовании pip
или easy_install
.
Ответ 2
Установите форму unidecode отсюда для поддержки Unicode
pip install unidecode
# -*- 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)
→ > my-custom-khello-vorld
Ответ 3
Существует пакет python с именем awesome-slugify:
pip install awesome-slugify
Работает следующим образом:
from slugify import slugify
slugify('one kožušček') # one-kozuscek
awesome-slugify github
Ответ 4
Проблема заключается в линии нормализации ascii:
slug = unicodedata.normalize('NFKD', s)
Он называется нормализация юникода, которая не разлагает множество символов на ascii. Например, он разделил бы символы не-ascii из следующих строк:
Mørdag -> mrdag
Æther -> ther
Лучший способ сделать это - использовать модуль unidecode, который пытается транслитерировать строки в ascii. Поэтому, если вы замените указанную выше строку:
import unidecode
slug = unidecode.unidecode(s)
Вы получите лучшие результаты для вышеупомянутых строк и для многих греческих и русских символов:
Mørdag -> mordag
Æther -> aether
Ответ 5
Он хорошо работает в Django, поэтому я не понимаю, почему это не будет хорошей функцией slugify общего назначения.
У вас возникли проблемы с этим?
Ответ 6
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
Это должно соответствовать вашим требованиям.
Ответ 7
Unidecode хорош; однако будьте осторожны: unidecode - это GPL. Если эта лицензия не подходит, используйте этот
Ответ 8
Вы можете рассмотреть возможность изменения последней строки на
slug=re.sub(r'--+',r'-',slug)
так как шаблон [-]+
не отличается от -+
, и вам действительно не нужно сопоставлять только один дефис, только два или более.
Но, конечно, это довольно незначительно.
Ответ 9
Пара параметров GitHub:
Каждый из них поддерживает несколько разных параметров для своего API, поэтому вам нужно посмотреть, что вы предпочитаете.
В частности, обратите внимание на различные варианты, которые они предоставляют для обработки символов, отличных от ASCII. Pydanny написал очень полезное сообщение в блоге, иллюстрирующее некоторые различия в обработке unicode в этих библиотеках slugify'ing: http://www.pydanny.com/awesome-slugify-human-readable-url-slugs-from-any-string.html Это сообщение в блоге немного устарело, потому что Mozilla unicode-slugify
больше не является Django-специфичным.
Также обратите внимание, что в настоящее время awesome-slugify
является GPLv3, хотя есть открытая проблема, когда автор говорит, что они предпочли бы выпускать как MIT/BSD, просто не уверены в законности: <а4 >