Auch die Django-Version von Slugify verwendet nicht das RE.UNICODE-Flag, also würde es nicht einmal versuchen, die Bedeutung von \w\s
zu verstehen, da es nicht-ASCII-Zeichen betrifft.
Diese kundenspezifische Version funktioniert gut für mich:
def u_slugify(txt):
"""A custom version of slugify that retains non-ascii characters. The purpose of this
function in the application is to make URLs more readable in a browser, so there are
some added heuristics to retain as much of the title meaning as possible while
excluding characters that are troublesome to read in URLs. For example, question marks
will be seen in the browser URL as %3F and are thereful unreadable. Although non-ascii
characters will also be hex-encoded in the raw URL, most browsers will display them
as human-readable glyphs in the address bar -- those should be kept in the slug."""
txt = txt.strip() # remove trailing whitespace
txt = re.sub('\s*-\s*','-', txt, re.UNICODE) # remove spaces before and after dashes
txt = re.sub('[\s/]', '_', txt, re.UNICODE) # replace remaining spaces with underscores
txt = re.sub('(\d):(\d)', r'\1-\2', txt, re.UNICODE) # replace colons between numbers with dashes
txt = re.sub('"', "'", txt, re.UNICODE) # replace double quotes with single quotes
txt = re.sub(r'[?,:[email protected]#~`+=$%^&\\*()\[\]{}<>]','',txt, re.UNICODE) # remove some characters altogether
return txt
Hinweis der letzte regex Substitution. Dies ist eine Abhilfe für ein Problem mit dem robusteren Ausdruck r'\W'
, die entweder einig Nicht-ASCII-Zeichen Streifen aus zu scheint oder falsch wieder kodieren sie, wie in der folgenden Python-Interpreter-Sitzung dargestellt:
Python 2.5.1 (r251:54863, Jun 17 2009, 20:37:34)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> # Paste in a non-ascii string (simplified Chinese), taken from http://globallives.org/wiki/152/
>>> str = '您認識對全球社區感興趣的中國攝影師嗎'
>>> str
'\xe6\x82\xa8\xe8\xaa\x8d\xe8\xad\x98\xe5\xb0\x8d\xe5\x85\xa8\xe7\x90\x83\xe7\xa4\xbe\xe5\x8d\x80\xe6\x84\x9f\xe8\x88\x88\xe8\xb6\xa3\xe7\x9a\x84\xe4\xb8\xad\xe5\x9c\x8b\xe6\x94\x9d\xe5\xbd\xb1\xe5\xb8\xab\xe5\x97\x8e'
>>> print str
您認識對全球社區感興趣的中國攝影師嗎
>>> # Substitute all non-word characters with X
>>> re_str = re.sub('\W', 'X', str, re.UNICODE)
>>> re_str
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\xa3\xe7\x9a\x84\xe4\xb8\xad\xe5\x9c\x8b\xe6\x94\x9d\xe5\xbd\xb1\xe5\xb8\xab\xe5\x97\x8e'
>>> print re_str
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX?的中國攝影師嗎
>>> # Notice above that it retained the last 7 glyphs, ostensibly because they are word characters
>>> # And where did that question mark come from?
>>>
>>>
>>> # Now do the same with only the last three glyphs of the string
>>> str = '影師嗎'
>>> print str
影師嗎
>>> str
'\xe5\xbd\xb1\xe5\xb8\xab\xe5\x97\x8e'
>>> re.sub('\W','X',str,re.U)
'XXXXXXXXX'
>>> re.sub('\W','X',str)
'XXXXXXXXX'
>>> # Huh, now it seems to think those same characters are NOT word characters
Ich bin unsicher, was das Problem oben ist, aber ich vermute, dass es von "" stammt, und wie das implementiert ist. Ich habe gehört, dass Python 3.x eine höhere Priorität bei der besseren Unicode-Behandlung hat, so dass dies bereits behoben sein könnte. Oder vielleicht ist es korrektes Python-Verhalten, und ich missbrauche Unicode und/oder die chinesische Sprache.
Vorerst ist es ein Workaround, Zeichenklassen zu vermeiden und Ersetzungen basierend auf explizit definierten Zeichensätzen vorzunehmen.
Dies ist wirklich eine wunderbare kleine lib. Diese Antwort sollte die akzeptierte sein. –
+1, nette lib! Einfach zu bedienen. – laike9m
es ist die pinyin-version der chinesischen, super nützlich! Vor allem, wenn Sie das Pinyin brauchen. –