Beyaz boşlukları alt çizgiyle nasıl değiştiririm?


221

Güzel URL'ler oluşturmak için boşlukları bir dizede alt çizgi ile değiştirmek istiyorum. Böylece, örneğin:

"This should be connected" becomes "This_should_be_connected" 

Django ile Python kullanıyorum. Bu düzenli ifadeler kullanılarak çözülebilir mi?


1
Bu nasıl django şablonunda elde edilebilir. Beyaz boşlukları kaldırmanın herhangi bir yolu var mı ? Bunu yapmak için yerleşik bir etiket / filtre var mı? Not: slugifyistenen çıktıyı vermez.
user1144616 12:12

Yanıtlar:


375

Normal ifadelere ihtiyacınız yok. Python, ihtiyacınız olanı yapan yerleşik bir dize yöntemine sahiptir:

mystring.replace(" ", "_")

29
Bu, \ t veya kesmeyen boşluk gibi diğer boşluk karakterleriyle çalışmaz.
Roberto Bonvallet

12
Evet haklısınız, ancak sorulan sorunun amacı için, diğer alanları dikkate almak gerekli görünmüyor.
rogeriopvl

1
bunun çalışması için herhangi bir şey almam gerekir mi? Aşağıdaki hatayı alıyorum: AttributeError: 'builtin_function_or_method' nesnesinin 'replace' özelliği yok
Ocasta Eshu

2
Muhtemelen replace adını verdiğiniz değişken bir dize türü değildi.
Snigdha Batra

5
Bu cevap kafa karıştırıcı olabilir, doğrudan dizeyi değiştirmediği yerine değiştirilmiş bir sürüm döndürdüğü için mystring = mystring.replace ("", "_") olarak yazmanız daha iyi olabilir.
Mehdi

79

Boşlukları değiştirmek iyidir, ancak soru işaretleri, kesme işaretleri, ünlem işaretleri vb.Gibi diğer URL düşmanca karakterleri işlemek için biraz daha ileri gitmenizi önerebilirim.

Ayrıca SEO uzmanları arasındaki genel fikir birliği, tire'lerin URL'lerde alt çizgilere tercih edildiğini unutmayın.

import re

def urlify(s):

    # Remove all non-word characters (everything except numbers and letters)
    s = re.sub(r"[^\w\s]", '', s)

    # Replace all runs of whitespace with a single dash
    s = re.sub(r"\s+", '-', s)

    return s

# Prints: I-cant-get-no-satisfaction"
print(urlify("I can't get no satisfaction!"))

Bu ilginç. Bu tavsiyeyi kesinlikle kullanacağım.
Lucas

Urllib.quote () 'u urlify ()' in çıktısını almayı unutmayın.
zgoda

1
Bu güzel - ancak \ RE ile ilk RE , sonraki RE'nin yerini alacak hiçbir şey olmadığı sonucu ile boşlukları da kaldıracaktır ... Diğer karakterlerinizi jetonlar arasında '-' ile değiştirmek istiyorsanız, ilk RE'yi bir belirtildiği gibi tek bir boşluk - örn. s = re.sub (r "\ W", '& nbsp', s) (bu StackOverflow'da çarpıcı bir biçimlendirme sorunu olabilir: meta.stackexchange.com/questions/105507/… )
tiluki

2
@Triptych Ne demek istiyorsun? Afrika ya da Avrupa kırlangıç?
2012'de

1
Bununla ilgili bir başka hafif sorun, url'deki önceden var olan tireleri kaldırmanızdır, böylece kullanıcı bu-temiz olmak için yüklemeden önce url dizesini temizlemeye çalışsaydı, bunu temizlemiş olur. Yani s = re.sub (r '[^ \ w \ s-]', '', s). Bir adım ileri gidebilir ve dosya adının sona ermemesi veya s = re.sub (r '[^ \ w \ s-]', '', s) ile bir tire ile başlamaması için önde gelen ve arkadaki boşlukları kaldırabilir. ()
Intenex

42

Django'nun bunu yapan bir 'slugify' işlevi ve diğer URL dostu optimizasyonlar vardır. Varsayılan filtreler modülünde gizlidir.

>>> from django.template.defaultfilters import slugify
>>> slugify("This should be connected")

this-should-be-connected

Bu tam olarak istediğiniz çıktı değildir, ancak IMO URL'lerde kullanmak daha iyidir.


Bu ilginç bir seçenek, ancak bu bir zevk meselesi mi yoksa alt çizgi yerine tire kullanmanın faydaları mı? Stackoverflow'un önerdiğiniz gibi kısa çizgiler kullandığını fark ettim. Ancak digg.com örneğin alt çizgi kullanır.
Lucas

Bu tercih edilen seçenek (AFAIK). Dizenizi alın, slugify, bir SlugField içinde saklayın ve modelinizin get_absolute_url () yönteminde kullanın. İnternetteki örnekleri kolayca bulabilirsiniz.
shanyu

3
@Lulu halkı tire kullanır çünkü uzun süre arama motorları tire işaretlerini kelime ayırıcı olarak ele alır ve böylece çok kelimeli aramalarda daha kolay bir zaman elde edersiniz.
James Bennett

@Daniel Roseman bunu dinamik olarak değişken olarak kullanabilir miyim? gerçek bir dize olarak dinamik web siteleri alıyorum gibi
kısa bir süre

Bu doğru cevap. URL'lerinizi sterilize etmeniz gerekir.
kagronick

40

Bu boşluk dışındaki boş karakterleri dikkate alır ve remodül kullanmaktan daha hızlı olduğunu düşünüyorum :

url = "_".join( title.split() )

4
Daha da önemlisi, herhangi bir boşluk karakteri veya boşluk karakterleri grubu için çalışacaktır.
dshepherd

Bu çözüm tüm boşluk karakterlerini işlemez. (örn. \x8f)
Lokal_Profil

İyi yakaladın, @Lokal_Profil! Dokümantasyon boşluk karakter dikkate alınır hangi belirtmez.
xOneca

1
Bu çözüm ayrıca, bölme () varsayılan "boşlukta böl" davranışı kullanıldığında boş öğeler döndürmediği için yinelenen sınırlayıcıları korumaz. Yani, girdi "merhaba, (burada 6 boşluk) dünya" ise, bu "merhaba, ______ dünya" yerine "merhaba, _dünya" ile sonuçlanır.
FliesLikeABrick

20

reModülü kullanma :

import re
re.sub('\s+', '_', "This should be connected") # This_should_be_connected
re.sub('\s+', '_', 'And     so\tshould this')  # And_so_should_this

Yukarıdaki gibi birden fazla alanınız veya diğer boşluk olanaklarınız yoksa, string.replacediğerlerinin önerdiği gibi kullanmak isteyebilirsiniz .


Teşekkür ederim, tam olarak istediğim buydu. Ama katılıyorum, "string.replace" görevim için daha uygun görünüyor.
Lucas

Ne halt, bunu yükseltmek istedim, ama bir nedenden dolayı indirildi ve şimdi oyum kilitlendi. Üzgünüm Jarret.
Dave Liu

10

string'in replace yöntemini kullanın:

"this should be connected".replace(" ", "_")

"this_should_be_disconnected".replace("_", " ")


6

Şaşırtıcı bir şekilde bu kütüphane henüz bahsedilmedi

Slugifying'ın oldukça iyi bir işini yapan python-slugify adlı python paketi:

pip install python-slugify

Şöyle çalışır:

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

5

Dost URL'lerim için aşağıdaki kod parçasını kullanıyorum:

from unicodedata import normalize
from re import sub

def slugify(title):
    name = normalize('NFKD', title).encode('ascii', 'ignore').replace(' ', '-').lower()
    #remove `other` characters
    name = sub('[^a-zA-Z0-9_-]', '', name)
    #nomalize dashes
    name = sub('-+', '-', name)

    return name

Unicode karakterlerle de iyi çalışır.


1
Bunun yerleşik Django slugify işlevinden nerede farklı olduğunu açıklayabilir misiniz?
Andy Baker

4

Python'un şu şekilde kullanılan replace adı verilen dizelerde yerleşik bir yöntemi vardır:

string.replace(old, new)

Yani şunu kullanırsınız:

string.replace(" ", "_")

Bir süre önce bu sorun vardı ve bir dize karakterleri değiştirmek için kod yazdı. Python belgelerini kontrol etmeyi hatırlamaya başlamalıyım çünkü her şey için fonksiyonlar var.


3

OP python kullanıyor, ancak javascript'te (sözdizimleri benzer olduğundan dikkat edilmesi gereken bir şey).

// only replaces the first instance of ' ' with '_'
"one two three".replace(' ', '_'); 
=> "one_two three"

// replaces all instances of ' ' with '_'
"one two three".replace(/\s/g, '_');
=> "one_two_three"

3
mystring.replace (" ", "_")

bu değeri herhangi bir değişkene atarsanız,

s = mystring.replace (" ", "_")

varsayılan olarak mystring buna sahip olmayacak



-3
perl -e 'map { $on=$_; s/ /_/; rename($on, $_) or warn $!; } <*>;'

Match et replace space> geçerli dizindeki tüm dosyaların alt çizgisi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.