Szukam najlepszego sposobu na "slugify" czym jest "slug" , a moje obecne rozwiązanie bazuje na tym przepisie
Zmieniłem to trochę na:
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)
Czy ktoś widzi jakieś problemy z tym kodem? Działa dobrze, ale może czegoś mi brakuje lub znasz lepszy sposób?
Odpowiedzi:
Istnieje pakiet o nazwie Python
python-slugify
, który całkiem nieźle radzi sobie ze slugowaniem:Działa tak:
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")
Zobacz więcej przykładów
Ten pakiet robi trochę więcej niż to, co opublikowałeś (spójrz na źródło, to tylko jeden plik). Projekt jest nadal aktywny (został zaktualizowany 2 dni przed pierwszą odpowiedzią, ponad siedem lat później (ostatnio sprawdzany 2020-06-30), nadal jest aktualizowany).
uwaga : w pobliżu jest drugi pakiet o nazwie
slugify
. Jeśli masz oba, możesz mieć problem, ponieważ mają tę samą nazwę do importu. Ten, który właśnie wymieniono,slugify
nie zrobił wszystkiego, co szybko sprawdziłem:"Ich heiße"
stał się"ich-heie"
(powinien być"ich-heisse"
), więc pamiętaj, aby wybrać właściwy, używającpip
lubeasy_install
.źródło
python-slugify
jest objęty licencją MIT, ale korzysta zUnidecode
licencji GPL, więc może nie pasować do niektórych projektów.python-slugify
domyślnie korzystatext-unidecode
z licencji artystycznej zamiast licencji GPLUnidecode
, rozwiązując Twoje problemy licencyjne. github.com/un33k/python-slugify/commit/…Zainstaluj stąd formularz unidecode , aby uzyskać obsługę 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)
źródło
slugify("My custom хелло ворлд")
sięslugify(u"My custom хелло ворлд")
, i to powinno działać.str
. To ukrywa wbudowanystr
typ.Istnieje pakiet Pythona o nazwie awesome-slugify :
Działa tak:
from slugify import slugify slugify('one kožušček') # one-kozuscek
Strona github awesome-slugify
źródło
slugify(text).lower()
jeśli tego chcesz.Działa dobrze w Django , więc nie rozumiem, dlaczego nie byłaby to dobra funkcja slugify ogólnego przeznaczenia.
Masz z tym jakieś problemy?
źródło
from django.utils.text import slugify
Problem dotyczy linii normalizacji ascii:
slug = unicodedata.normalize('NFKD', s)
Nazywa się to normalizacją Unicode, która nie rozkłada wielu znaków na ascii. Na przykład usunie znaki inne niż ASCII z następujących ciągów:
Lepszym sposobem na zrobienie tego jest użycie modułu unidecode , który próbuje transliterować ciągi znaków na ascii. Więc jeśli zamienisz powyższą linię na:
import unidecode slug = unidecode.unidecode(s)
Uzyskasz lepsze wyniki dla powyższych ciągów, a także dla wielu znaków greckich i rosyjskich:
źródło
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)
To jest funkcja slugify obecna w django.utils.text. To powinno wystarczyć.
źródło
Unidecode jest dobry; jednak uważaj: unidecode to GPL. Jeśli ta licencja nie pasuje, użyj tej
źródło
Kilka opcji na GitHub:
Każdy obsługuje nieco inne parametry swojego interfejsu API, więc musisz przejrzeć, aby dowiedzieć się, co wolisz.
W szczególności zwróć uwagę na różne opcje, jakie zapewniają one w przypadku znaków spoza zestawu ASCII. Pydanny napisał bardzo pomocny post na blogu, ilustrujący niektóre różnice w obsłudze Unicode w tych bibliotekach slugify: http://www.pydanny.com/awesome-slugify-human-readable-url-slugs-from-any-string.html Ten wpis na blogu jest nieco nieaktualny, ponieważ Mozilla nie
unicode-slugify
jest już specyficzna dla Django.Zwróć również uwagę, że obecnie
awesome-slugify
jest to GPLv3, chociaż istnieje otwarty problem, w którym autor mówi, że wolałby wydać jako MIT / BSD, ale nie jest pewien legalności: https://github.com/dimka665/awesome-slugify/issues/ 24źródło
Możesz rozważyć zmianę ostatniej linii na
slug=re.sub(r'--+',r'-',slug)
ponieważ wzorzec
[-]+
nie różni się od wzorca-+
i nie zależy Ci na dopasowaniu tylko jednego łącznika, tylko dwóch lub więcej.Ale oczywiście jest to dość drobne.
źródło
Inną opcją jest
boltons.strutils.slugify
. Boltons ma również kilka innych przydatnych funkcji i jest rozpowszechniany naBSD
licencji.źródło