我想从字符串中删除所有奇怪的字符,使其“url safe”。因此,我有一个这样的功能:
def urlize(url, safe=u''):
intab = u"àáâãäåòóôõöøèéêëçìíîïùúûüÿñ" + safe
outtab = u"aaaaaaooooooeeeeciiiiuuuuyn" + safe
trantab = dict((ord(a), b) for a, b in zip(intab, outtab))
return url.lower().translate(trantab).strip()
这很好用,但现在我想重用那个功能来允许特殊字符。例如,引号。
urlize(u'This is sóme randóm "text" that í wánt to process',u'"')
...并抛出以下错误:
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: expected a character buffer object
我试过了,但没有奏效:
urlize(u'text',u'\"')
intab = u"àáâãäåòóôõöøèéêëçìíîïùúûüÿñ%s" , safe
- 编辑 - 完整功能看起来像这样
def urlize(url, safe=u''):
intab = u"àáâãäåòóôõöøèéêëçìíîïùúûüÿñ" + safe
outtab = u"aaaaaaooooooeeeeciiiiuuuuyn" + safe
trantab = dict((ord(a), b) for a, b in zip(intab, outtab))
translated_url = url.lower().translate(trantab).strip()
pos = 0
stop = len(translated_url)
new_url= ''
last_division_char = False
while pos < stop:
if not translated_url[pos].isalnum() and translated_url[pos] not in safe:
if (not last_division_char) and (pos != stop -1):
new_url+='-'
last_division_char = True
else:
new_url+=translated_url[pos]
last_division_char = False
pos+=1
return new_url
- 编辑 - 目标
我想要的是规范化文本,以便我可以将其自己放在网址上,并像使用Id一样使用它。例如,如果我想展示一个类别的产品,我宁愿把“ninos-y-bebes”代替“niños-y-bebés”(西班牙语为孩子和婴儿)。我真的不想要我的网址中的所有áéíóúñ(这是西班牙语中的特殊字符),但我也不想摆脱它们。这就是为什么我想替换看起来相同的所有字符(不是100%所有字符,我都不在乎)然后删除所有非字母数字字符。
答案 0 :(得分:6)
unidecode模块是一个更安全的选项(它将处理其他特殊的符号,如“度”):
>>> from unidecode import unidecode
>>> s = u'This is sóme randóm "text" that í wánt to process'
>>> unidecode(s)
'This is some random "text" that i want to process'
>>> import urllib
>>> urllib.urlencode(dict(x=unidecode(s)))[2:]
'This+is+some+random+%22text%22+that+i+want+to+process'
[更新]
我想我已经这样做了 - &gt;你是“aaaaaaooooooeeeeeeciiiiuuuuyn” - Marco Bruggmann
很公道,如果你愿意跟踪你的翻译表中的每个unicode字符(重音字符不是唯一的问题,你的游行中会有很多符号下雨)。
最糟糕的是,许多unicode符号在视觉上与它们的ASCII对应符号相同,导致难以诊断错误。
[更新]
如下:
>>> safe_chars = 'abcdefghijklmnopqrstuvwxyz01234567890-_'
>>> filter(lambda x: x in safe_chars, "i think i'm already doing that")
'ithinkimalreadydoingthat'
[更新]
@Daenyth我试过了,但我只收到错误:来自urllib import urlencode =&gt; urlencode('google.com/';)=&gt; TypeError:不是有效的非字符串序列或映射对象 - Marco Bruggmann
urlencode函数用于产生QUERYSTRING格式化输出(a = 1&amp; b = 2&amp; c = 3)。它期望键/值对:
>>> urllib.urlencode(dict(url='google.com/'))
'url=google.com%2F'
>>> help(urllib.urlencode)
Help on function urlencode in module urllib:
urlencode(query, doseq=0)
Encode a sequence of two-element tuples or dictionary into a URL query string.
If any values in the query arg are sequences and doseq is true, each
sequence element is converted to a separate parameter.
If the query arg is a sequence of two-element tuples, the order of the
parameters in the output will match the order of parameters in the
input.
(END)
[更新]
这将毫无疑问地运作,但我想要的是规范化文本,以便我可以将其自己放在网址上,并像使用Id一样使用它。例如,如果我想展示一个类别的产品,我宁愿把“ninos-y-bebes”代替“niños-y-bebés”(西班牙语为孩子和婴儿)。我真的不想要我的网址中的所有áéíóúñ(这是西班牙语中的特殊字符),但我也不想摆脱它们。这就是为什么我想替换看起来相同的所有字符(不是100%所有字符,我都不在乎)然后删除所有非字母数字字符。
好的,Marco,你想要的是创建所谓的slugs的常规,不是吗?
您可以在一行中完成:
>>> s = u'This is sóme randóm "text" that í wánt to process'
>>> allowed_chars = 'abcdefghijklmnopqrstuwvxyz01234567890'
>>> ''.join([ x if x in allowed_chars else '-' for x in unidecode(s.lower()) ])
u'this-is-some-random--text--that-i-want-to-process'
>>> s = u"Niños y Bebés"
>>> ''.join([ x if x in allowed_chars else '-' for x in unidecode(s.lower()) ])
u'ninos-y-bebes'
>>> s = u"1ª Categoria, ½ docena"
>>> ''.join([ x if x in allowed_chars else '-' for x in unidecode(s.lower()) ])
u'1a-categoria--1-2-docena'