2009-06-17 11 views
119

Quiero reemplazar espacios en blanco con guión bajo en una cadena para crear buenas URL. Así que, por ejemplo:¿Cómo reemplazo los espacios en blanco con guión bajo y viceversa?

"This should be connected" becomes "This_should_be_connected" 

Estoy usando Python con Django. ¿Se puede resolver esto usando expresiones regulares?

+0

¿Cómo puede lograrse esto en Plantilla django. ¿Hay alguna manera de ** eliminar ** espacios en blanco. ¿Hay alguna etiqueta/filtro incorporado para hacer esto? Nota: 'slugify' no da el resultado deseado. – user1144616

Respuesta

218

No necesita expresiones regulares. Python tiene incorporado un método de cadena que hace lo que necesita:

mystring.replace(" ", "_") 
+15

Esto no funciona con otros espacios en blanco, como \ t o un espacio sin interrupciones. –

+10

Sí, tiene razón, pero a los fines de la pregunta, no parece necesario tener en cuenta esos otros espacios. – rogeriopvl

+1

¿Necesito importar algo para que esto funcione? Me aparece el siguiente error: AttributeError: el objeto 'builtin_function_or_method' no tiene ningún atributo 'replace' –

13

Con el módulo de re:

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 menos que tenga múltiples espacios u otras posibilidades de espacio en blanco que el anterior, es posible que sólo desee use string.replace como otros han sugerido.

+0

Gracias, esto era exactamente lo que estaba pidiendo. Pero estoy de acuerdo, el "string.replace" parece más adecuado para mi tarea. – Lucas

8

cadena uso de reemplazar el método:

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

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

55

espacios Sustitución está muy bien, pero podría sugerir ir un poco más lejos para manejar otros caracteres de URL hostil como signos de interrogación, apóstrofes de exclamación puntos, etc.

También tenga en cuenta que el consenso general entre los expertos de SEO es que dashes are preferred to underscores in URLs.

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

Esto es interesante. Definitivamente usaré este consejo. – Lucas

+0

Recuerde urllib.quote() el resultado de su urlify() - ¿y si s contiene algo que no sea ascii? – zgoda

+1

Esto es bueno, pero el primer RE con \ W * también eliminará espacios en blanco * con el resultado de que el RE siguiente no tiene nada que reemplazar ... Si desea reemplazar sus otros caracteres con '-' entre tokens, tenga el primer RE reemplace con un espacio único como se indica, es decir, s = re.sub (r "\ W", '& nbsp', s) (este puede ser un problema de formato shonky en StackOverflow: http://meta.stackexchange.com/questions/ 105507/cómo agregar espacio en la sección de código) – timlukins

36

Django tiene una función 'slugify' que hace esto, así como otras optimizaciones de URL optimizadas. Está escondido en el módulo defaultfilters.

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

this-should-be-connected 

Este no es exactamente el resultado que solicitó, pero IMO es mejor para su uso en las URL.

+0

Esa es una opción interesante, pero ¿es esto una cuestión de gusto o cuáles son los beneficios de usar guiones en lugar de guiones bajos? Me di cuenta de que Stackoverflow usa guiones como usted sugiere. Pero digg.com, por ejemplo, usa guiones bajos. – Lucas

+0

Esta es la opción preferida (AFAIK). Toma tu cadena, slugifícala, guárdala en un SlugField y úsala en la get_absolute_url() de tu modelo. Puedes encontrar ejemplos en la red fácilmente. – shanyu

+3

@Lulu las personas usan guiones porque, durante mucho tiempo, los motores de búsqueda han tratado los guiones como separadores de palabras, por lo que le resultaría más fácil aparecer en las búsquedas de varias palabras. –

4

estoy usando el siguiente fragmento de código para mis urls amigables:

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 

Funciona bien con caracteres Unicode también.

+1

¿Podría explicarnos en qué se diferencia esto de la función incorporada Django slugify? –

2

Python ha incorporado un método de cadenas de llamadas en lugar de que se utiliza como modo:

string.replace(old, new) 

Por lo tanto se debería utilizar:

string.replace(" ", "_") 

he tenido este problema hace un tiempo y he escrito código para reemplazar caracteres en una cadena. Tengo que empezar a recordar revisar la documentación de Python porque tienen funciones integradas para todo.

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

Partido et reemplazar espacio> subrayado de todos los archivos en el directorio actual

2

OP está utilizando Python, pero en javascript (algo que tener cuidado ya que los de sintaxis son similares.

// 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" 
25

Esto toma en cuenta los caracteres en blanco que no sean el espacio y yo creo que es más rápido que usar re módulo:

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

Más importante aún, funcionará para cualquier carácter en espacio en blanco o grupo de caracteres en espacio en blanco. – dshepherd

+0

Esta solución no maneja todos los caracteres de espacio en blanco. (por ejemplo, ['\ x8f'] (http://www.charbase.com/008f-unicode-single-shift-three)) –

+0

¡Buena captura, @Lokal_Profil! La [documentación] (https://docs.python.org/2/library/stdtypes.html#str.split) no especifica qué caracteres en blanco se tienen en cuenta. – xOneca

1

Sorprendentemente esta biblioteca no menciona sin embargo

pitón paquete llamado python-slugify, que hace un muy buen trabajo de slugifying:

pip install python-slugify 

funciona así:

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

si asigna este valor a una variable, que funcionará

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

por mystring por defecto no tendrá este

Cuestiones relacionadas