私は文字列を「スラッグ化」する最良の方法を探しています 「スラッグ」とは何ですか 、そして現在の解決策は このレシピ に基づいています
私はそれを少し変更しました:
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という名前のパッケージ 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に最後にチェックされました)、まだ更新されています)。
careful:slugify
という名前の2つ目のパッケージがあります。両方を使用している場合、インポートの名前が同じであるため、問題が発生する可能性があります。 slugify
という名前のものは、私が簡単にチェックしたすべてを実行しませんでした:"Ich heiße"
は"ich-heie"
になりました("ich-heisse"
になります) pip
またはeasy_install
を使用する場合。
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
pythonという名前のパッケージ awesome-slugify :
pip install awesome-slugify
このように動作します:
from slugify import slugify
slugify('one kožušček') # one-kozuscek
問題は、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
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です。このライセンスが適合しない場合は、 this one を使用します
GitHubのいくつかのオプション:
それぞれが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
最後の行を
slug=re.sub(r'--+',r'-',slug)
パターン[-]+
は-+
と変わらないため、2つ以上のハイフンを1つだけ一致させる必要はありません。
しかし、もちろん、これは非常に小さなものです。
別のオプションは boltons.strutils.slugify
。 ボルトン には他にも便利な機能がいくつかあり、BSD
ライセンスで配布されています。