Come posso sostituire gli spazi bianchi con trattino basso e viceversa?


221

Voglio sostituire gli spazi bianchi con trattino basso in una stringa per creare simpatici URL. In modo che ad esempio:

"This should be connected" becomes "This_should_be_connected" 

Sto usando Python con Django. Questo può essere risolto usando espressioni regolari?


1
Come è possibile ottenere questo risultato nel modello django. Esiste un modo per rimuovere gli spazi bianchi. C'è qualche tag / filtro integrato per fare questo? Nota: slugifynon fornisce l'output desiderato.
user1144616

Risposte:


375

Non hai bisogno di espressioni regolari. Python ha un metodo stringa incorporato che fa quello che ti serve:

mystring.replace(" ", "_")

29
Questo non funziona con altri caratteri di spazi bianchi, come \ t o uno spazio non interrotto.
Roberto Bonvallet,

12
Sì, hai ragione, ma ai fini della domanda posta, non sembra necessario prendere in considerazione quegli altri spazi.
rogeriopvl,

1
devo importare qualcosa affinché funzioni? Ottengo il seguente errore: AttributeError: l'oggetto 'builtin_function_or_method' non ha alcun attributo 'sostituisci'
Ocasta Eshu

2
Probabilmente la variabile che hai chiamato sostituire non era un tipo di stringa.
Snigdha Batra,

5
Questa risposta potrebbe essere confusa, meglio scriverla come mystring = mystring.replace ("", "_") poiché non modifica direttamente la stringa ma piuttosto restituisce una versione modificata.
Mehdi,

79

Sostituire gli spazi va bene, ma potrei suggerire di andare un po 'oltre per gestire altri caratteri ostili all'URL come punti interrogativi, apostrofi, punti esclamativi, ecc.

Si noti inoltre che il consenso generale tra gli esperti SEO è che i trattini sono preferiti ai caratteri di sottolineatura negli URL.

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

Questo è interessante. Userò sicuramente questo consiglio.
Lucas,

Ricorda di urllib.quote () l'output di urlify () - cosa succede se s contiene qualcosa di non ascii?
zgoda,

1
Questo è carino - ma il primo RE con \ W rimuoverà anche gli spazi bianchi con il risultato che il RE successivo non ha nulla da sostituire ... Se vuoi sostituire i tuoi altri caratteri con '-' tra i token, il primo RE sostituisce con un spazio singolo come indicato - ovvero s = re.sub (r "\ W", '& nbsp', s) (potrebbe trattarsi di un problema di formattazione sfuggente su StackOverflow: meta.stackexchange.com/questions/105507/… )
tiluki

2
@Triptych Che vuoi dire? Rondine africana o europea?
Kyoto

1
Un altro piccolo problema con questo è che rimuovi tutti i trattini preesistenti nell'URL, in modo che se l'utente avesse tentato di pulire la stringa dell'URL prima di caricare per essere questo-è-pulito, verrebbe rimosso da questo disco. Quindi s = re.sub (r '[^ \ w \ s-]', '', s). Può fare un ulteriore passo avanti e rimuovere gli spazi iniziali e finali in modo che il nome file non finisca o inizi con un trattino con s = re.sub (r '[^ \ w \ s-]', '', s) .strip ()
Intenex,

42

Django ha una funzione 'slugify' che lo fa, così come altre ottimizzazioni ottimizzate per gli URL. È nascosto nel modulo defaultfilters.

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

this-should-be-connected

Questo non è esattamente l'output richiesto, ma IMO è migliore per l'utilizzo negli URL.


Questa è un'opzione interessante, ma è una questione di gusti o quali sono i vantaggi dell'uso di trattini anziché di sottolineature. Ho appena notato che Stackoverflow utilizza trattini come suggerisci tu. Ma digg.com ad esempio usa caratteri di sottolineatura.
Lucas,

Questa sembra essere l'opzione preferita (AFAIK). Prendi la tua stringa, slugificala, salvala in una SlugField e usala nel get_absolute_url () del tuo modello. Puoi trovare facilmente esempi sulla rete.
Shanyu,

3
Le persone di @Lulu usano i trattini perché, per lungo tempo, i motori di ricerca hanno trattato i trattini come separatori di parole e quindi avresti più tempo a trovarti nelle ricerche su più parole.
James Bennett,

@Daniel Roseman posso usarlo con variabili dinamiche. come sto ottenendo siti Web dinamici come stringa in un vero e proprio
effimero

Questa è la risposta esatta. Devi disinfettare i tuoi URL.
kagronick,

40

Questo tiene conto dei caratteri vuoti diversi dallo spazio e penso che sia più veloce dell'uso del remodulo:

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

4
Ancora più importante funzionerà per qualsiasi carattere di spazio bianco o gruppo di caratteri di spazio bianco.
pastore

Questa soluzione non gestisce tutti i caratteri degli spazi bianchi. (es. \x8f)
Lokal_Profil,

Buona cattura, @Lokal_Profil! La documentazione non specifica quali caratteri di spazi bianchi sono presi in considerazione.
xOneca,

1
Questa soluzione non manterrà inoltre i delimitatori ripetuti, poiché split () non restituisce elementi vuoti quando si utilizza il comportamento predefinito "split on whitespace". Cioè, se l'input è "ciao, (6 spazi qui) mondo", ciò comporterà "ciao, _mondo" come output, piuttosto che "ciao, ______ mondo".
FliesLikeABrick il

20

Utilizzando il remodulo:

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

A meno che tu non abbia più spazi o altre possibilità di spazi bianchi come sopra, potresti semplicemente voler usare string.replacecome altri hanno suggerito.


Grazie, questo era esattamente quello che stavo chiedendo. Ma sono d'accordo, "string.replace" sembra più adatto al mio compito.
Lucas,

Che diamine, volevo votare questo, ma per qualche ragione è stato annullato il voto e ora il mio voto è bloccato. Scusa Jarret.
Dave Liu,

10

usa il metodo di sostituzione della stringa:

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

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


6

Sorprendentemente questa biblioteca non è ancora stata menzionata

pacchetto python chiamato python-slugify, che fa un ottimo lavoro di slugify:

pip install python-slugify

Funziona così:

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

Sto usando il seguente codice per i miei URL amichevoli:

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

Funziona bene anche con i caratteri Unicode.


1
Potresti spiegare dove questo differisce dalla funzione slugify di Django integrata?
Andy Baker,

4

Python ha un metodo integrato su stringhe chiamato sostituisci che viene utilizzato come segue:

string.replace(old, new)

Quindi useresti:

string.replace(" ", "_")

Ho avuto questo problema qualche tempo fa e ho scritto codice per sostituire i caratteri in una stringa. Devo iniziare a ricordare di controllare la documentazione di Python perché hanno funzioni integrate per tutto.


3

OP sta usando python, ma in javascript (qualcosa da fare attenzione poiché le sintassi sono simili.

// 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 (" ", "_")

se assegni questo valore a qualsiasi variabile, funzionerà

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

per impostazione predefinita mystring non avrà questo



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

Abbina e sostituisci spazio> carattere di sottolineatura di tutti i file nella directory corrente

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.