पायथन में स्ट्रिंग स्लगिफिकेशन


96

मैं "स्लगिफ़" स्ट्रिंग का सबसे अच्छा तरीका खोज रहा हूं कि "स्लग" क्या है , और मेरा वर्तमान समाधान इस नुस्खा पर आधारित है

मैंने इसे थोड़ा बदल दिया है:

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)

किसी को भी इस कोड के साथ कोई समस्या देखते हैं? यह ठीक काम कर रहा है, लेकिन शायद मुझे कुछ याद आ रहा है या आप एक बेहतर तरीका जानते हैं?


क्या आप यूनिकोड के साथ काम कर रहे हैं? यदि ऐसा है, तो अंतिम re.sub बेहतर हो सकता है यदि आप इसके चारों ओर यूनिकोड () लपेटते हैं, तो यह django करता है। इसके अलावा, [^ a-z0-9] + का उपयोग छोटा किया जा सकता है। django.template.defaultfilters देखें, यह आपके करीब है, लेकिन थोड़ा और अधिक परिष्कृत।
माइक रामिरेज़

क्या यूनिकोड वर्णों को URL में अनुमति दी गई है? इसके अलावा, मैंने \ w को a-z0-9 में बदल दिया है, क्योंकि \ w में _ वर्ण और अपरकेस अक्षर शामिल हैं। पत्रों को पहले से कम करने के लिए सेट किया गया है, इसलिए मैच के लिए कोई बड़े अक्षर नहीं होंगे।
ज़िगिमांतास

'_' वैध है (लेकिन आपकी पसंद, आपने पूछा था), यूनिकोड प्रतिशत एन्कोडेड वर्ण है।
माइक रामिरेज़

धन्यवाद माइक। खैर, मैंने एक गलत सवाल पूछा। क्या इसे यूनिकोड स्ट्रिंग में वापस एनकोड करने का कोई कारण है, अगर हमने "az", "0-9" और "-" को छोड़कर सभी वर्णों को पहले ही बदल दिया है?
ज़िगिमांतास

Django के लिए, मेरा मानना ​​है कि संगतता के लिए यूनिकोड ऑब्जेक्ट के रूप में यह सभी तार होना उनके लिए महत्वपूर्ण है। यदि आप ऐसा चाहते हैं तो यह आपकी पसंद है।
माइक रामिरेज़

जवाबों:


146

नाम का एक अजगर पैकेज है 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 दिन पहले अपडेट हो गई, सात साल बाद (अंतिम बार 2020-06-30 की जांच की गई), यह अभी भी अपडेट हो गई है)।

सावधान : नाम के आसपास एक दूसरा पैकेज है slugify। यदि आपके पास दोनों हैं, तो आपको समस्या हो सकती है, क्योंकि उनके पास आयात के लिए समान नाम है। एक बस नामित slugifyसब मैं जल्दी जाँच नहीं किया: "Ich heiße"बन गया "ich-heie"(होना चाहिए "ich-heisse"), इसलिए का उपयोग करते समय, सही एक लेने के लिए सुनिश्चित हो pipया easy_install


6
python-slugifyएमआईटी के तहत लाइसेंस प्राप्त है, लेकिन इसका उपयोग Unidecodeजीपीएल के तहत लाइसेंस प्राप्त है, इसलिए यह कुछ परियोजनाओं के लिए फिट नहीं हो सकता है।
रोटेरेटी

@Rotareti क्या आप मेरे लिए यह समझा सकते हैं कि यह सभी परियोजनाओं के लिए उपयुक्त क्यों नहीं हो सका? क्या हम MIT या GPL लाइसेंस के तहत कुछ भी उपयोग नहीं कर सकते हैं और उन्हें वाणिज्यिक सॉफ़्टवेयर के अंदर शामिल कर सकते हैं? मुझे लगता है कि एकमात्र प्रतिबंध हमारे द्वारा विकसित कोड के अलावा लाइसेंस डाल रहा है। क्या मै गलत हु?
घासेम टोफि जूल

1
@GhassemTofighi संक्षेप में: आप इसे अपने वाणिज्यिक सॉफ़्टवेयर में उपयोग कर सकते हैं, लेकिन यदि आप इसका उपयोग करते हैं, तो आपको अपने कोड को भी स्रोत खोलना होगा। वैसे भी IANAL और यह कोई कानूनी सलाह नहीं है।
रोटारटी

@GhassemTofighi शायद इस विषय पर softwareengineering.stackexchange.com/q/47032/71504 पर एक नज़र डालें
kratenko

1
@Rotareti python-slugifyअब text-unidecodeGPL- लाइसेंस के बजाय आर्टिस्टिक लाइसेंस के लिए डिफॉल्ट करता है Unidecode, आपके लाइसेंस की चिंता को संबोधित करता है। github.com/un33k/python-slugify/commit/…
एमिलन

31

यूनिकोड समर्थन के लिए यहाँ से यूनिडॉब फॉर्म को स्थापित करें

पाइप स्थापित करें

# -*- 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)

>>> मेरी-प्रथा-खालो-वचन


1
नमस्ते, यह थोड़ा अजीब है, लेकिन यह मेरे रेस के लिए इस तरह देता है कि "मेरे-कस्टम-ndud-d-d3-4-d2d3-4nd-d-"
derevo

1
जब आप यूनिकोड के तार नहीं भेजते हैं तो @derevo खुश होता है। बदलें slugify("My custom хелло ворлд")के साथ slugify(u"My custom хелло ворлд"), और यह काम करना चाहिए।
kratenko

9
मैं जैसे चर नामों का उपयोग करने के खिलाफ सुझाव दूंगा str। यह बिलिन strप्रकार को छुपाता है ।
crodjer

2
यूनिडबॉस GPL है, जो कुछ के लिए उपयुक्त नहीं हो सकता है।
जॉर्ज लीताओ

पुनर्विक्रेता या डिस्लुगिंग के बारे में क्या।
रयान चो

11

अजब-गजब नाम का अजगर पैकेज है :

pip install awesome-slugify

इस तरह काम करता है:

from slugify import slugify

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

भयानक-सुस्त गितूब पेज


2
अच्छा पैकेज! लेकिन सावधान रहें, यह जीपीएल के तहत लाइसेंस प्राप्त है।
रोटेरेटी

1
सिर ऊपर: यह स्वचालित रूप से .lower () आपके url नहीं होगा। slugify(text).lower()यदि आप चाहते हैं कि आप को चलाने की आवश्यकता होगी ।
कलोब ताउलियन

7

यह Django में अच्छा काम करता है , इसलिए मैं यह नहीं देखता कि यह एक अच्छा सामान्य उद्देश्य क्यों नहीं होगा।

क्या आपको इससे कोई समस्या है?


यह संभव है, कि कुछ मामलों के लिए, यह व्यामोह की एक स्वस्थ खुराक है :-)
nemesisfixx

कोड यहाँ ले जाया गया है
रेअल्लू

13
लज़ीज़ के लिए:from django.utils.text import slugify
स्पार्टाकस

6

समस्या एससीआई सामान्यीकरण लाइन के साथ है:

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

इसे यूनिकोड सामान्यीकरण कहा जाता है जो बहुत सारे पात्रों को असिसी के लिए विघटित नहीं करता है। उदाहरण के लिए, यह निम्नलिखित तार से गैर-अस्की अक्षर खींचेगा:

Mørdag -> mrdag
Æther -> ther

इसका एक बेहतर तरीका यह है कि यूनिडॉस्कोप मॉड्यूल का उपयोग किया जाए जो कि स्ट्रैस को ascii में बदलने की कोशिश करता है। इसलिए यदि आप उपरोक्त लाइन को इसके साथ बदलते हैं:

import unidecode
slug = unidecode.unidecode(s)

उपरोक्त तार के लिए और कई ग्रीक और रूसी पात्रों के लिए भी आपको बेहतर परिणाम मिले:

Mørdag -> mordag
Æther -> aether

5
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 फ़ंक्शन है। यह आपकी आवश्यकता को पूरा करना चाहिए।



2

GitHub पर कुछ विकल्प:

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

प्रत्येक अपने एपीआई के लिए थोड़ा अलग मापदंडों का समर्थन करता है, इसलिए आपको यह देखने की आवश्यकता होगी कि आप क्या पसंद करते हैं।

विशेष रूप से, गैर-एएससीआईआई पात्रों से निपटने के लिए उनके द्वारा प्रदान किए जाने वाले विभिन्न विकल्पों पर ध्यान दें। Pydanny ने एक बहुत ही उपयोगी ब्लॉग पोस्ट लिखी जिसमें इन slugify'ing पुस्तकालयों में कुछ यूनिकोड हैंडलिंग अंतरों को दर्शाया गया है: http://www.pydanny.com/awesome-slugify-human-readable-url-slugs-from-any-string.html यह ब्लॉग पोस्ट थोड़ा पुराना है क्योंकि मोज़िला हैunicode-slugify अब Django- विशिष्ट नहीं है।

यह भी ध्यान दें कि वर्तमान awesome-slugifyमें GPLv3 है, हालांकि एक खुला मुद्दा है जहां लेखक कहता है कि वे एमआईटी / बीएसडी के रूप में रिलीज़ करना पसंद करेंगे, बस वैधता के बारे में सुनिश्चित नहीं है: https://github.com/dimka665/awesome-slugetET/issues/ 24


1

आप अंतिम पंक्ति को बदलने पर विचार कर सकते हैं

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

चूंकि पैटर्न [-]+से अलग नहीं है -+, और आप वास्तव में केवल एक हाइफ़न, केवल दो या अधिक मिलान के बारे में परवाह नहीं करते हैं।

लेकिन, ज़ाहिर है, यह काफी मामूली है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.