Как заменить пробелы подчеркиванием и наоборот?

105

Я хочу заменить пробел символом подчеркивания в строке, чтобы создать хорошие URL-адреса. Так что, например:

"This should be connected" becomes "This_should_be_connected" 

Я использую Python с Django. Можно ли это решить с помощью регулярных выражений?

  • 1
    Как это может быть достигнуто в шаблоне Django. Есть ли способ убрать пробелы. Есть ли встроенный тег / фильтр для этого? Примечание: slugify не дает желаемого результата.
Теги:

12 ответов

213
Лучший ответ

Вам не нужны регулярные выражения. Python имеет встроенный строковый метод, который делает то, что вам нужно:

mystring.replace(" ", "_")
  • 19
    Это не работает с другими пробельными символами, такими как \ t или неразрывный пробел.
  • 11
    Да, вы правы, но для целей поставленного вопроса, кажется, нет необходимости принимать во внимание эти другие пробелы.
Показать ещё 3 комментария
49

Замена пространств в порядке, но я мог бы предложить немного поработать с другими URL-враждебными символами, такими как вопросительные знаки, апострофы, восклицательные знаки и т.д.

Также обратите внимание, что общее мнение экспертов SEO заключается в том, что тире предпочтительнее подчеркивать в URL-адресах.

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
    Это интересно. Я обязательно воспользуюсь этим советом.
  • 0
    Не забудьте urllib.quote () вывод вашего urlify () - что если s содержит что-то не ascii?
Показать ещё 4 комментария
35

Django имеет функцию "slugify", которая делает это, а также другие оптимизирующие URL-адреса оптимизацию. Он скрыт в модуле defaultfilters.

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

this-should-be-connected

Это не совсем тот результат, который вы просили, но IMO лучше использовать в URL-адресах.

  • 0
    Это интересный вариант, но это вопрос вкуса или каковы преимущества использования дефисов вместо подчеркивания. Я только что заметил, что Stackoverflow использует дефисы, как вы предлагаете. Но digg.com, например, использует подчеркивание.
  • 0
    Это оказывается предпочтительным вариантом (AFAIK). Возьмите свою строку, зарежьте ее, сохраните в SlugField и используйте ее в get_absolute_url () вашей модели. Вы можете легко найти примеры в сети.
Показать ещё 3 комментария
23

Это учитывает пробельные символы, отличные от пробела, и я думаю, что это быстрее, чем с помощью модуля re:

url = "_".join( title.split() )
  • 4
    Что еще более важно, это будет работать для любого символа пробела или группы символов пробела.
  • 0
    Это решение не обрабатывает все пробельные символы. (например, \x8f )
Показать ещё 2 комментария
13

Используя модуль 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

Если у вас есть несколько пробелов или другие пробелы, как указано выше, вы можете просто использовать string.replace, как предложили другие.

  • 0
    Спасибо, это было именно то, что я просил. Но я согласен, "string.replace" кажется более подходящим для моей задачи.
8

использовать метод замены строки:

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

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

4

Я использую следующий фрагмент кода для моих дружественных URL-адресов:

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

Он отлично работает с символами юникода.

  • 1
    Не могли бы вы объяснить, чем это отличается от встроенной функции Slugify Django?
2

Python имеет встроенный метод для строк, называемых replace, который используется как таковой:

string.replace(old, new)

Итак, вы должны использовать:

string.replace(" ", "_")

У меня была эта проблема некоторое время назад, и я написал код для замены символов в строке. Я должен начать вспоминать, чтобы проверить документацию на python, потому что у них есть встроенные функции для всего.

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

если вы присвоите это значение любой переменной, оно будет работать

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

по умолчанию у mystring не будет этого

1

Удивительно, что эта библиотека еще не упоминалась

пакет python с именем python-slugify, который выполняет довольно хорошую работу:

pip install python-slugify

Работает следующим образом:

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

OP использует python, но в javascript (нужно быть осторожным, поскольку синтаксисы похожи.

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

Match et replace space > подчеркивание всех файлов в текущем каталоге

Ещё вопросы

Сообщество Overcoder
Наверх
Меню