如何用下划线替换空格,反之亦然?


220

我想用字符串中的下划线替换空格以创建漂亮的URL。因此,例如:

"This should be connected" becomes "This_should_be_connected" 

我在Django中使用Python。可以使用正则表达式解决吗?


1
如何在Django模板中实现这一点。有什么办法可以删除空格。有内置的标签/过滤器可以做到这一点吗?注意:slugify未提供所需的输出。
user1144616 2012年

Answers:


373

您不需要正则表达式。Python有一个内置的字符串方法可以满足您的需要:

mystring.replace(" ", "_")

29
这不适用于其他空格字符,例如\ t或不间断空格。
罗伯托·邦瓦莱特2009年

12
是的,您是正确的,但出于所提问题的目的,似乎没有必要考虑其他空格。
rogeriopvl

1
我需要导入任何东西才能正常工作吗?我得到以下错误:AttributeError的:“builtin_function_or_method”对象有没有属性“取代”
Ocasta Eshu

2
您调用replace的变量可能不是字符串类型。
Snigdha Batra 2015年

4
这个答案可能会令人困惑,最好将其写为mystring = mystring.replace(“”,“ _”),因为它不会直接更改字符串,而是返回更改后的版本。
Mehdi

79

替换空格是可以的,但我建议您进一步处理其他对URL不利的字符,例如问号,撇号,感叹号等。

还要注意,SEO专家之间的普遍共识是,在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!"))

这是有趣的。我一定会使用这个建议。
卢卡斯2009年

记住要urllib.quote()的urlify()的输出-如果s包含非ASCII内容怎么办?
zgoda

1
很好-但是第一个带有\ W的RE 也会删除空格,结果后续的RE无需替换...如果要在标记之间用'-'替换其他字符,则第一个RE可以用如所示的单个空格-即s = re.sub(r“ \ W”,'&nbsp',s)(这可能是StackOverflow上的一个笨拙的格式问题:meta.stackexchange.com/questions/105507/…
tiluki

2
@Triptych是什么意思?非洲人还是欧洲人吞下?
tiluki 2012年

1
另一个小问题是,您删除了url中所有先前存在的连字符,因此,如果用户在上载为“此为干净”之前尝试清理url字符串,它将被剥离为“ thisisclean”。所以s = re.sub(r'[^ \ w \ s-]','',s)。可以更进一步,删除开头和结尾的空格,以使文件名不会结尾或以s = re.sub(r'[^ \ w \ s-]','',s)开头的连字符开头。 ()
Intenex

42

Django具有执行此功能的“ slugify”功能以及其他对URL友好的优化。它隐藏在defaultfilters模块中。

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

this-should-be-connected

这不完全是您要求的输出,但是IMO最好在URL中使用。


这是一个有趣的选择,但这是一个趣味问题,还是使用连字符代替下划线的好处是什么?我刚刚注意到,Stackoverflow使用像您建议的连字符。但是digg.com例如使用下划线。
卢卡斯2009年

这恰好是首选选项(AFAIK)。拿起您的字符串,将其分段,将其存储在SlugField中,并在模型的get_absolute_url()中使用它。您可以在网上轻松找到示例。
shanyu

3
@Lulu人们使用破折号是因为,很长一段时间以来,搜索引擎都将破折号视为单词分隔符,因此您在多单词搜索中会更轻松。
James Bennett

@Daniel Roseman我可以将其与动态变量一起使用吗?因为我正在以一个切实的方式获取动态网站为字符串
短暂,

这是正确的答案。您需要清理URL。
kagronick

40

这考虑了空格以外的空白字符,我认为它比使用re模块要快:

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

4
更重要的是,它将适用于任何空白字符或空白字符组。
牧羊人

此解决方案不能处理所有空白字符。(例如\x8f
Lokal_Profil '16

好收获,@ Lokal_Profil!该文档没有指定要考虑的空格字符。
xOneca '16

1
此解决方案也不会保留重复的定界符,因为在使用默认的“在空格上分割”行为时split()不会返回空项目。也就是说,如果输入为“ hello,(此处为6个空格)world”,则会导致输出“ hello,_world”,而不是“ hello,______ world”。
FliesLikeABrick

20

使用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按照其他人的建议使用即可。


谢谢,这正是我要的。但是我同意,“ string.replace”似乎更适合我的任务。
卢卡斯2009年

什么意思,我的意思是赞成,但是由于某种原因,它被否决了,现在我的投票已锁定。对不起,贾雷特。
戴夫·刘

10

使用字符串的replace方法:

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

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


6

令人惊讶的是,这个图书馆还没有提到

名为python-slugify的python包,可以很好地完成slugizing:

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

5

我将以下代码用于我的友好网址:

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

Unicode字符也可以正常工作。


1
您能否解释一下这与内置的Django slugify函数有何不同?
安迪·贝克

4

Python在名为replace的字符串上有一个内置方法,其使用方式如下:

string.replace(old, new)

因此,您将使用:

string.replace(" ", "_")

前一段时间我遇到了这个问题,我编写了代码来替换字符串中的字符。我必须开始记得检查python文档,因为它们已经内置了所有功能。


3

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

如果将此值分配给任何变量,它将起作用

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

默认情况下,mystring不会有这个



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

匹配并替换空间>​​当前目录中所有文件的下划线

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.