2009-06-17 4 views
119

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

"This should be connected" becomes "This_should_be_connected" 

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

+0

Как это может это быть достигнуто шаблон django. Есть ли способ ** удалить ** пробелы. Есть ли встроенный тег/фильтр для этого? Примечание: 'slugify' не дает желаемого результата. – user1144616

ответ

218

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

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

Это не работает с другими символами пробела, такими как \ t или неразрывное пространство. –

+10

Да, вы правы, но для целей заданного вопроса нет необходимости учитывать эти другие пространства. – rogeriopvl

+1

Мне нужно импортировать что-нибудь для этого, чтобы работать? Я получаю следующую ошибку: объект AttributeError: 'builtin_function_or_method' не имеет атрибута 'replace' –

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» кажется более подходящим для моей задачи. – Lucas

8

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

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

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

55

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

Также обратите внимание, что общий консенсус среди экспертов в области SEO заключается в том, что 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

Это интересно. Я определенно буду использовать этот совет. – Lucas

+0

Помните urllib.quote() вывод вашего urlify() - что если s содержит что-то не-ascii? – zgoda

+1

Это хорошо - но первый RE с \ W будет * также удалять пробелы *, в результате чего последующий RE ничего не заменит ... Если вы хотите заменить ваши другие символы «-» между токенами, есть первый RE замените единым пространством, как указано, т.е. s = re.sub (r "\ W", '& nbsp', s) (это может быть проблема форматирования shonky в StackOverflow: http://meta.stackexchange.com/questions/ 105507/how-to-add-a-space-in-code-section) – timlukins

36

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, например, использует символы подчеркивания. – Lucas

+0

Это предпочтительный вариант (AFAIK). Возьмите свою строку, снимите ее, сохраните в SlugField и используйте ее в get_absolute_url() вашей модели. Вы можете легко найти примеры в сети. – shanyu

+3

Пользователи @Lulu используют тире, потому что долгое время поисковые системы обрабатывали тире как разделители слов, и поэтому вам приходилось легче искать многопользовательские поиски. –

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

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

2

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

string.replace(old, new) 

Таким образом, вы будете использовать:

string.replace(" ", "_") 

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

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

Match и др заменить пробел> подчеркивание всех файлов в текущем каталоге

2

OP использует питона, но в 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" 
25

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

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

Что еще более важно, он будет работать для любого символа пробела или группы символов пробелов. – dshepherd

+0

Это решение не обрабатывает все пробельные символы. (например, ['\ x8f'] (http://www.charbase.com/008f-unicode-single-shift-three)) –

+0

Хороший улов, @Lokal_Profil! В [документации] (https://docs.python.org/2/library/stdtypes.html#str.split) не указывается, какие символы пробелов учитываются. – xOneca

1

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

питона пакет с именем питон-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
mystring.replace (" ", "_") 

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

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

по умолчанию MyString имеют обыкновение это

Смежные вопросы