Python中的string段落
我正在寻找“slugify”string什么“slug”是最好的方法,我目前的解决scheme是基于这个配方
我已经改变了一点点:
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-slugify
的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
。 如果你有两个人,你可能会遇到一个问题,因为他们有相同的名称import。 刚刚命名为slugify
人没有做所有的快速检查: "Ich heiße"
变成"ich-heie"
(应该是"ich-heisse"
),所以在使用pip
或easy_install
时一定要select正确的。
从这里安装unidecodeforms为unicode支持
点子安装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
有一个叫做awesome-slugify的 python包:
pip install awesome-slugify
像这样工作:
from slugify import slugify slugify('one kožušček') # one-kozuscek
awesome-slugify github页面
问题在于ascii标准化行:
slug = unicodedata.normalize('NFKD', s)
它被称为unicode规范化 ,它不分解大量的字符ascii。 例如,它会从以下string中去除非ASCII字符:
Mørdag -> mrdag Æther -> ther
更好的方法是使用试图将string转换为ascii的unidecode模块。 所以如果你用上面的行代替:
import unidecode slug = unidecode.unidecode(s)
对于上面的string和许多希腊和俄罗斯的字符,你会得到更好的结果:
Mørdag -> mordag Æther -> aether
它在Django中运行的很好,所以我不明白为什么它不是一个好的通用slugify函数。
你有什么问题吗?
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)
这是django.utils.text中的slugify函数。这应该满足您的要求。
Unidecode是好的; 但是,请注意:unidecode是GPL。 如果这个许可证不适合,然后使用这一个
你可能会考虑改变最后一行
slug=re.sub(r'--+',r'-',slug)
因为模式[-]+
和-+
没有区别,所以你并不关心匹配一个连字符,只有两个或更多。
但是,当然,这是相当小的。
GitHub上有几个选项:
- https://github.com/dimka665/awesome-slugify
- https://github.com/un33k/python-slugify
- https://github.com/mozilla/unicode-slugify
每个API都支持稍微不同的参数,所以你需要仔细看看你喜欢什么。
特别要注意它们提供的用于处理非ASCII字符的不同选项。 Pydanny写了一个非常有用的博客文章,说明这些slugify图书馆的一些unicode处理差异: http ://www.pydanny.com/awesome-slugify-human-readable-url-slugs-from-any-string.html这个博客文章稍微过时了,因为Mozilla的unicode-slugify
不再是Django特有的。
另外请注意,目前awesome-slugify
是GPLv3,虽然有一个开放的问题,作者说,他们宁愿发布为麻省理工学院/ BSD,只是不确定的合法性: https : //github.com/dimka665/awesome-slugify /问题/ 24