Wie ersetze ich Leerzeichen durch Unterstriche und umgekehrt?

220

Ich möchte Leerzeichen durch Unterstriche in einer Zeichenfolge ersetzen, um nette URLs zu erstellen. So dass zum Beispiel:

"This should be connected" becomes "This_should_be_connected" 

Ich benutze Python mit Django. Kann dies mit regulären Ausdrücken gelöst werden?

Lucas
quelle
1
Wie kann dies in der Django-Vorlage erreicht werden? Gibt es eine Möglichkeit , Leerzeichen zu entfernen ? Gibt es ein eingebautes Tag / Filter, um dies zu tun? Hinweis: slugifyGibt nicht die gewünschte Ausgabe.
user1144616

Antworten:

373

Sie brauchen keine regulären Ausdrücke. Python verfügt über eine integrierte Zeichenfolgenmethode, die genau das tut, was Sie benötigen:

mystring.replace(" ", "_")
rogeriopvl
quelle
29
Dies funktioniert nicht mit anderen Leerzeichen wie \ t oder einem nicht unterbrechenden Leerzeichen.
Roberto Bonvallet
12
Ja, Sie haben Recht, aber für die gestellte Frage scheint es nicht notwendig zu sein, diese anderen Leerzeichen zu berücksichtigen.
Rogeriopvl
1
Muss ich etwas importieren, damit dies funktioniert? Ich erhalte die folgende Fehlermeldung: AttributeError: Das Objekt 'builtin_function_or_method' hat kein Attribut 'replace'
Ocasta Eshu
2
Wahrscheinlich war die Variable, für die Sie Ersetzen aufgerufen haben, kein Zeichenfolgentyp.
Snigdha Batra
4
Diese Antwort könnte verwirrend sein. Schreiben Sie sie besser als mystring = mystring.replace ("", "_"), da sie den String nicht direkt ändert, sondern eine geänderte Version zurückgibt.
Mehdi
79

Das Ersetzen von Leerzeichen ist in Ordnung, aber ich könnte vorschlagen, etwas weiter zu gehen, um andere URL-feindliche Zeichen wie Fragezeichen, Apostrophe, Ausrufezeichen usw. zu behandeln.

Beachten Sie auch, dass der allgemeine Konsens unter SEO-Experten darin besteht, dass Bindestriche den Unterstrichen in URLs vorgezogen werden.

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!"))
Triptychon
quelle
Das ist interessant. Ich werde diesen Rat auf jeden Fall verwenden.
Lucas
Denken Sie daran, die Ausgabe von urlify () auf urllib.quote () zu setzen - was ist, wenn s etwas enthält, das nicht von ASCII stammt?
Zgoda
1
Das ist schön - aber die erste RE mit \ W entfernt auch Leerzeichen mit dem Ergebnis, dass die nachfolgende RE nichts zu ersetzen hat ... Wenn Sie Ihre anderen Zeichen durch '-' zwischen Token ersetzen möchten, lassen Sie die erste RE durch a ersetzen einzelnes Leerzeichen wie angegeben - dh s = re (r "\ W", '& nbsp', s) (dies kann ein Problem bei der Formatierung von StackOverflow sein: meta.stackexchange.com/questions/105507/… )
tiluki
2
@ Triptychon Was meinst du? Afrikanische oder europäische Schwalbe?
Tiluki
1
Ein weiteres kleines Problem dabei ist, dass Sie alle bereits vorhandenen Bindestriche in der URL entfernen. Wenn der Benutzer vor dem Hochladen versucht hat, die URL-Zeichenfolge zu bereinigen, um sie "is-is-clean" zu sein, wird sie auf "thisisclean" entfernt. Also s = re (r '[^ \ w \ s-]', '', s). Kann einen Schritt weiter gehen und führende und nachfolgende Leerzeichen entfernen, damit der Dateiname nicht mit einem Bindestrich mit s = re (r '[^ \ w \ s-]', '', s) .strip endet oder beginnt ()
Intenex
42

Django verfügt über eine Slugify-Funktion sowie andere URL-freundliche Optimierungen. Es ist im Standardfilter-Modul versteckt.

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

this-should-be-connected

Dies ist nicht genau die Ausgabe, nach der Sie gefragt haben, aber IMO ist es besser für die Verwendung in URLs.

Daniel Roseman
quelle
Das ist eine interessante Option, aber ist dies eine Frage des Geschmacks oder was sind die Vorteile der Verwendung von Bindestrichen anstelle von Unterstrichen? Mir ist gerade aufgefallen, dass Stackoverflow Bindestriche verwendet, wie Sie es vorschlagen. Digg.com verwendet beispielsweise Unterstriche.
Lucas
Dies ist zufällig die bevorzugte Option (AFAIK). Nehmen Sie Ihren String, slugifizieren Sie ihn, speichern Sie ihn in einem SlugField und verwenden Sie ihn in get_absolute_url () Ihres Modells. Sie können Beispiele im Internet leicht finden.
Shanyu
3
@ Lulu-Leute verwenden Bindestriche, weil Suchmaschinen Bindestriche lange Zeit als Worttrennzeichen behandelt haben und Sie bei der Suche nach mehreren Wörtern leichter auftauchen können.
James Bennett
@ Daniel Roseman kann ich dies mit dynamisch variablen verwenden. wie ich dynamische Websites als Zeichenfolge in einem verifizierbaren
kurzlebigen
Das ist die richtige Antwort. Sie müssen Ihre URLs bereinigen.
Kagronick
40

Dies berücksichtigt andere leere Zeichen als Leerzeichen und ich denke, es ist schneller als die Verwendung von reModulen:

url = "_".join( title.split() )
xOneca
quelle
4
Noch wichtiger ist, dass es für alle Leerzeichen oder Gruppen von Leerzeichen funktioniert.
Dshepherd
Diese Lösung verarbeitet nicht alle Leerzeichen. (zB \x8f)
Lokal_Profil
Guter Fang, @Lokal_Profil! In der Dokumentation wird nicht angegeben, welche Leerzeichen berücksichtigt werden.
xOneca
1
Diese Lösung behält auch keine Wiederholungsbegrenzer bei, da split () keine leeren Elemente zurückgibt, wenn das Standardverhalten "Auf Leerzeichen teilen" verwendet wird. Das heißt, wenn die Eingabe "Hallo, (6 Leerzeichen hier) Welt" ist, führt dies zu "Hallo, _Welt" als Ausgabe und nicht zu "Hallo, ______ Welt".
FliesLikeABrick
20

Verwenden des reModuls:

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

Sofern Sie nicht wie oben über mehrere Leerzeichen oder andere Leerzeichen string.replaceverfügen, möchten Sie diese möglicherweise nur verwenden, wie andere vorgeschlagen haben.

Jarret Hardie
quelle
Danke, genau darum habe ich gebeten. Aber ich stimme zu, der "string.replace" scheint für meine Aufgabe besser geeignet zu sein.
Lucas
Was zum Teufel, ich wollte das upvoten, aber aus irgendeinem Grund wurde es downvotiert und jetzt ist meine Stimme gesperrt. Sorry Jarret.
Dave Liu
10

Verwenden Sie die Ersetzungsmethode des Strings:

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

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

mdirolf
quelle
6

Überraschenderweise wurde diese Bibliothek noch nicht erwähnt

Python-Paket mit dem Namen python-slugify, das ziemlich gute Arbeit beim Slugifizieren leistet:

pip install python-slugify

Funktioniert so:

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") 
Yash
quelle
5

Ich verwende den folgenden Code für meine freundlichen URLs:

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

Es funktioniert auch gut mit Unicode-Zeichen.

Armandas
quelle
1
Können Sie erklären, wo sich dies von der integrierten Django-Slugify-Funktion unterscheidet?
Andy Baker
4

Python verfügt über eine integrierte Methode für Zeichenfolgen namens replace, die wie folgt verwendet wird:

string.replace(old, new)

Sie würden also verwenden:

string.replace(" ", "_")

Ich hatte dieses Problem vor einiger Zeit und schrieb Code, um Zeichen in einer Zeichenfolge zu ersetzen. Ich muss daran denken, die Python-Dokumentation zu überprüfen, da sie Funktionen für alles eingebaut hat.


quelle
3

OP verwendet Python, jedoch in Javascript (etwas, auf das Sie achten müssen, da die Syntax ähnlich ist.

// 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"
Twmulloy
quelle
3
mystring.replace (" ", "_")

Wenn Sie diesen Wert einer Variablen zuweisen, funktioniert er

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

Standardmäßig hat mystring dies nicht

Rajesh
quelle
3

Sie können dies stattdessen versuchen:

mystring.replace(r' ','-')
Meghaa Yadav
quelle
-3
perl -e 'map { $on=$_; s/ /_/; rename($on, $_) or warn $!; } <*>;'

Übereinstimmen und Ersetzen des Leerzeichens> Unterstrich aller Dateien im aktuellen Verzeichnis


quelle