Python - 格式化字符串为URL的最短方法

3 投票
6 回答
3624 浏览
提问于 2025-04-18 03:10

我正在参与一个网页项目。现在我需要选择最好的方式来展示代码,这样其他人看起来不会觉得困难或者头疼。

我现在遇到的“问题”是如何把一个漂亮格式的链接展示出来(这个链接会从一个“标题”字符串中获取)。

假设我们有一个标题,是从表单中获取的:

title = request.form['title'] # 'Hello World, Hello Cat! Hello?'

接下来,我们需要一个函数来把这个标题格式化,以便放到链接里(它需要变成 'hello_world_hello_cat_hello' 这样的格式),所以目前我用的这个函数我觉得可读性不太好:

str.replace(title, ' ', '-').str.replace(title, '!', '').str.replace(title, '?', '').str.replace(string, ',' '').lower()

有没有什么好的方法可以让它更简洁一些?有没有现成的函数可以做我正在做的事情?

我还想知道在链接中应该去掉哪些字符或符号。

6 个回答

0

我的意思是,你可以把它分成多个语句:

str = str.replace(title, ' ', '-')
str = str.replace(title, '!', '')
str = str.replace(title, '?', '')
str = str.replace(string, ',' '')
str = str.lower()

这样会让代码更容易阅读。

3

我试着玩了你们所有的答案,得出了一些结果。

注意:这些“基准测试”不需要太认真对待,因为我没有考虑所有可能的方案,但这是一种快速了解整体情况的好方法。

re.findall()

def findall():
  string = 'Hello World, Hello Cat! Hello?'
  return  '_'.join(re.findall(r'\w+',string)).lower()

实际时间=0.019秒,用户时间=0.012秒,系统时间=0.004秒,大致时间=0.016秒

re.sub()

def sub():
  string = 'Hello World, Hello Cat! Hello?'
  return re.sub(r'\W+','_',string).lower()

实际时间=0.020秒,用户时间=0.016秒,系统时间=0.004秒,大致时间=0.020秒

slugify()

def slug():
  string = 'Hello World, Hello Cat! Hello?'
  return slugify(string)

实际时间=0.031秒,用户时间=0.024秒,系统时间=0.004秒,大致时间=0.028秒

urllib.urlencode()

def urlenc():
  string = {'title': 'Hello World, Hello Cat! Hello?'}
  return urllib.urlencode(string)

实际时间=0.036秒,用户时间=0.024秒,系统时间=0.008秒,大致时间=0.032秒

从结果来看,最快的是 re.findall(),最慢的是 urllib.urlencode(),而 slugify() 则在中间,虽然它不是最快的,但它是所有方法中最简洁的。

目前我选择的是 Slugify,就像在斗犬中间的幸运猫一样。

3

你可以在Python2中使用urllib模块里的urlencode(),或者在Python3中使用urllib.parse模块里的urlencode()

这样做是基于你想把文本放在网址的查询字符串里。

title = {'title': 'Hello World, Hello Cat! Hello?'} # or get it programmatically as you did
encoded = urllib.urlencode(title)
print encoded # title=Hello+World%2C+Hello+Cat%21+Hello%3F
5

你可以使用urlencode()这个方法,它是Python中进行URL编码字符串的标准方式。

如果你想要一种个性化的编码方式,只想保留最终字符串中的单词,可以使用re.findall函数来提取这些单词,然后用下划线把它们连接起来:

>>>s = 'Hello World, Hello Cat! Hello?'
>>>'_'.join(re.findall(r'\w+',s)).lower()
'hello_world_hello_cat_hello'

这个方法的作用是:

g = re.findall(r'\w+',s) # ['Hello', 'World', 'Hello', 'Cat', 'Hello']
s1 = '_'.join(g) # 'Hello_World_Hello_Cat_Hello'
s1.lower() # 'hello_world_hello_cat_hello'

这种技巧对字符串中的数字也很有效:

>>>s = 'Hello World, Hello Cat! H123ello? 123'
>>>'_'.join(re.findall(r'\w+',s)).lower()
'hello_world_hello_cat_h123ello_123'

还有一种我认为应该更快的方法,就是直接替换掉那些不是字母或数字的字符。可以用re.sub来实现,把所有非字母数字的字符一起抓取,然后用_替换掉,像这样:

>>>re.sub(r'\W+','_',s).lower()
'hello_world_hello_cat_h123ello_123'

不过……实际上并不是这样,速度测试:

$python -mtimeit -s "import re" -s "s='Hello World, Hello Cat! Hello?'" "'_'.join(re.findall(r'\w+',s)).lower()"
100000 loops, best of 3: 5.08 usec per loop


$python -mtimeit -s "import re" -s "s='Hello World, Hello Cat! Hello?'" "re.sub(r'\W+','_',s).lower()"
100000 loops, best of 3: 6.55 usec per loop
1
import re
re.sub(r'!|\?|,', '', text)

这段代码会把字符串中的感叹号、问号和逗号去掉。

撰写回答