with websites mastering libro learn for development book beginning beginners application and python slug

python - websites - mastering django core



Slugification de cadenas en Python (9)

El problema es con la línea de normalización ascii:

slug = unicodedata.normalize(''NFKD'', s)

Se llama normalización unicode que no descompone muchos caracteres en ascii. Por ejemplo, eliminaría caracteres no ascii de las siguientes cadenas:

Mørdag -> mrdag Æther -> ther

Una mejor forma de hacerlo es usar el módulo unidecode que intenta transliterar cadenas a ascii. Entonces si reemplaza la línea anterior con:

import unidecode slug = unidecode.unidecode(s)

Obtendrá mejores resultados para las cadenas anteriores y para muchos caracteres griegos y rusos también:

Mørdag -> mordag Æther -> aether

Estoy en busca de la mejor manera de "slugificar" la secuencia de lo que es "slug" , y mi solución actual se basa en esta receta

Lo he cambiado un poco para:

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)

¿Alguien ve algún problema con este código? Está funcionando bien, pero tal vez me falta algo o ¿sabes una mejor manera?


Funciona bien en Django , así que no veo por qué no sería una buena función slugify de propósito general.

¿Tienes algún problema con eso?



Hay un paquete de python llamado python-slugify , que hace un buen trabajo de slugifying:

pip install python-slugify

Funciona así:

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")

Ver más ejemplos

Este paquete hace un poco más de lo que publicaste (echa un vistazo a la fuente, es solo un archivo). El proyecto aún está activo (se actualizó 2 días antes de que respondiera originalmente, más de cuatro años después (se verificó por última vez el 2017-04-26), todavía se actualiza).

cuidado : hay un segundo paquete, llamado slugify . Si tiene ambos, es posible que tenga un problema, ya que tienen el mismo nombre para importar. El que acabo de slugify no hizo todo lo que comprobé rápidamente: "Ich heiße" convirtió en "ich-heie" (debería ser "ich-heisse" ), así que asegúrese de elegir el correcto, cuando use pip o easy_install .


Instalar el formulario unidecode desde aquí para soporte 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-world


Puede considerar cambiar la última línea a

slug=re.sub(r''--+'',r''-'',slug)

ya que el patrón [-]+ no es diferente de -+ , y realmente no le importa emparejar solo un guión, solo dos o más.

Pero, por supuesto, esto es bastante menor.


Un par de opciones en GitHub:

  1. https://github.com/dimka665/awesome-slugify
  2. https://github.com/un33k/python-slugify
  3. https://github.com/mozilla/unicode-slugify

Cada uno admite parámetros ligeramente diferentes para su API, por lo que deberá consultar para descubrir qué prefiere.

En particular, preste atención a las diferentes opciones que ofrecen para tratar con caracteres que no son ASCII. Pydanny escribió una muy útil publicación de blog que ilustra algunas de las diferencias de manejo unicode en estas bibliotecas de slugify: http://www.pydanny.com/awesome-slugify-human-readable-url-slugs-from-any-string.html Esta publicación de blog está un poco desactualizada porque el unicode-slugify ya no es específico de Django.

También tenga en cuenta que actualmente awesome-slugify es GPLv3, aunque hay un problema abierto en el que el autor dice que preferiría publicarlo como MIT / BSD, simplemente no está seguro de la legalidad: https://github.com/dimka665/awesome-slugify / issues / 24


Unidecode es bueno; sin embargo, tenga cuidado: unidecode es GPL. Si esta licencia no cabe, utiliza esta


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)

Esta es la función slugify presente en django.utils.text Esto debería ser suficiente.