web-dev-qa-db-ja.com

Pythonの文字列スラギフィケーション

私は文字列を「スラッグ化」する最良の方法を探しています 「スラッグ」とは何ですか 、そして現在の解決策は このレシピ に基づいています

私はそれを少し変更しました:

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)

誰でもこのコードに問題がありますか?それはうまく機能していますが、何かが欠けているか、より良い方法を知っていますか?

76
Zygimantas

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

その他の例 を参照してください

このパッケージは、あなたが投稿したものよりも少し多くのことを行います(ソースを見てください。1つのファイルです)。プロジェクトはまだアクティブです(最初に応答する2日前に更新されましたが、4年後(2017-04-26に最後にチェックされました)、まだ更新されています)。

carefulslugifyという名前の2つ目のパッケージがあります。両方を使用している場合、インポートの名前が同じであるため、問題が発生する可能性があります。 slugifyという名前のものは、私が簡単にチェックしたすべてを実行しませんでした:"Ich heiße""ich-heie"になりました("ich-heisse"になります) pipまたはeasy_installを使用する場合。

122
kratenko

Unidecodeフォームをインストールします ここから Unicodeサポート用

pide 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

28
user1078810

pythonという名前のパッケージ awesome-slugify

pip install awesome-slugify

このように動作します:

from slugify import slugify

slugify('one kožušček')  # one-kozuscek

awesome-slugify githubページ

10
voronin

問題は、ASCII正規化ラインにあります。

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

これは nicode normalization と呼ばれ、多くの文字をASCIIに分解しません。たとえば、次の文字列から非ASCII文字を削除します。

Mørdag -> mrdag
Æther -> ther

より良い方法は、文字列をasciiに音訳しようとする nidecode モジュールを使用することです。したがって、上記の行を次のように置き換えた場合:

import unidecode
slug = unidecode.unidecode(s)

上記の文字列と、多くのギリシャ語とロシア語の文字についても、より良い結果が得られます。

Mørdag -> mordag
Æther -> aether
6

Django でうまく機能するので、なぜそれが良い汎用のslugify関数ではないのかわかりません。

何か問題がありますか?

6
Nick Presta
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関数です。これで要件は十分です。

5
Animesh Sharma

Unidecodeは良いです。ただし、注意してください:unidecodeはGPLです。このライセンスが適合しない場合は、 this one を使用します

3
Mikhail Korobov

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'ingライブラリのUnicode処理の違いのいくつかを示す非常に役立つブログ記事を書きました。 http://www.pydanny.com/awesome-slugify-human-readable-url-slugs-from-any -string.html このブログ投稿は、Mozillaのunicode-slugifyはDjango固有ではなくなりました。

また、現在awesome-slugifyはGPLv3ですが、作者がMIT/BSDとしてリリースすることを望んでいると言っている未解決の問題がありますが、合法性は確かではありません: https://github.com/dimka665/awesome-slugify/ issues/24

2
Jeff Widman

最後の行を

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

パターン[-]+-+と変わらないため、2つ以上のハイフンを1つだけ一致させる必要はありません。

しかし、もちろん、これは非常に小さなものです。

1
unutbu

別のオプションは boltons.strutils.slugifyボルトン には他にも便利な機能がいくつかあり、BSDライセンスで配布されています。

0
ostrokach