Respuestas:
No necesitas expresiones regulares. Python tiene un método de cadena incorporado que hace lo que necesita:
mystring.replace(" ", "_")
Reemplazar espacios está bien, pero podría sugerir ir un poco más lejos para manejar otros caracteres hostiles a las URL como signos de interrogación, apóstrofes, signos de exclamación, etc.
También tenga en cuenta que el consenso general entre los expertos de SEO es que los guiones son preferibles a los guiones bajos en las 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!"))
Django tiene una función 'slugify' que hace esto, así como otras optimizaciones amigables con URL. Está oculto en el módulo de filtros predeterminados.
>>> 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 usar en URL.
Esto tiene en cuenta los caracteres en blanco que no sean el espacio y creo que es más rápido que usar el re
módulo:
url = "_".join( title.split() )
\x8f
. ej. )
Usando el re
módulo:
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 espacios en blanco como se mencionó anteriormente, es posible que desee utilizar string.replace
como otros han sugerido.
Sorprendentemente, esta biblioteca aún no se menciona
paquete de python llamado python-slugify, que hace un muy buen trabajo de slugify:
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")
Estoy usando el siguiente código para mis URL 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.
Python tiene un método incorporado en cadenas llamado replace que se usa así:
string.replace(old, new)
Entonces usarías:
string.replace(" ", "_")
Tuve este problema hace un tiempo y escribí un código para reemplazar los caracteres en una cadena. Tengo que empezar a recordar comprobar la documentación de Python porque tienen funciones integradas para todo.
OP está usando Python, pero en JavaScript (algo a tener en cuenta ya que las 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"
Puedes probar esto en su lugar:
mystring.replace(r' ','-')
perl -e 'map { $on=$_; s/ /_/; rename($on, $_) or warn $!; } <*>;'
Match et replace space> guión bajo de todos los archivos en el directorio actual
slugify
no da el resultado deseado.