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" ),所以在使用pipeasy_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上有几个选项:

  1. https://github.com/dimka665/awesome-slugify
  2. https://github.com/un33k/python-slugify
  3. 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