سؤال

ولدي سلسلة الشفرة مثل "Tanım" التي يتم ترميز كما "٪ u0131m تان" بطريقة أو بأخرى. كيف يمكنني تحويل هذه السلسلة المشفرة إلى يونيكود الأصلي. يبدو urllib.unquote لا يدعم يونيكود.

هل كانت مفيدة؟

المحلول

و٪ uXXXX هو غير القياسية نظام ترميز التي كانت رفضته W3C، على الرغم من أن التنفيذ لا يزال يعيش على الأرض في جافا سكريبت.

وهذه التقنية الأكثر شيوعا ويبدو أن لUTF-8 ترميز السلسلة ومن ثم٪ هربا من وحدات البايت الناتجة باستخدام٪ XX. ويدعم هذا البرنامج من قبل urllib.unquote:

>>> urllib2.unquote("%0a")
'\n'

ولسوء الحظ، إذا كنت حقا على الحاجة لدعم٪ uXXXX، سيكون لديك ربما للفة فك الخاص بك. خلاف ذلك، فمن المرجح أن تكون أكثر من الأفضل ببساطة UTF-8 ترميز يونيكود وثم٪ هربا من وحدات البايت الناتجة عن ذلك.

وهناك مثال أكثر اكتمالا:

>>> u"Tanım"
u'Tan\u0131m'
>>> url = urllib.quote(u"Tanım".encode('utf8'))
>>> urllib.unquote(url).decode('utf8')
u'Tan\u0131m'

نصائح أخرى

def unquote(text):
    def unicode_unquoter(match):
        return unichr(int(match.group(1),16))
    return re.sub(r'%u([0-9a-fA-F]{4})',unicode_unquoter,text)

وهذا سوف نفعل ذلك إذا كان لديك على الاطلاق أن يكون هذا (أنا حقا لا أتفق مع صرخات "غير قياسي"):

from urllib import unquote

def unquote_u(source):
    result = unquote(source)
    if '%u' in result:
        result = result.replace('%u','\\u').decode('unicode_escape')
    return result

print unquote_u('Tan%u0131m')

> Tanım

وهناك خلل في الصيغة أعلاه حيث النزوات أحيانا عندما يكون هناك كل من أسكي ترميز يونيكود وترميز الحروف في السلسلة. وأعتقد أن لها خصيصا عندما تكون هناك شخصيات من 128 النطاق العلوي مثل '\ xab "بالإضافة إلى يونيكود.

وعلى سبيل المثال. "٪ 5B٪ AB٪ u03E1٪ BB٪ 5D" تسبب هذا الخطأ.

ولقد وجدت إذا فعلت فقط يونيكود منها أولا، وذهب بعيدا المشكلة:

def unquote_u(source):
  result = source
  if '%u' in result:
    result = result.replace('%u','\\u').decode('unicode_escape')
  result = unquote(result)
  return result

ولديك URL باستخدام غير القياسية نظام ترميز رفضت من قبل الهيئات المعنية بوضع المعايير ولكن لا يزال يتم إنتاجها من قبل بعض الترميز. وظيفة urllib.parse.unquote() بيثون لا يمكن معالجة هذه.

وإنشاء وحدة فك الترميز الخاصة بك ليس من الصعب، لحسن الحظ. وتهدف إدخالات %uhhhh أن <م> UTF-16 codepoints هنا، لذلك نحن بحاجة إلى اتخاذ <لأ href = "https://en.wikipedia.org/wiki/UTF-16#U+010000_to_U+10FFFF "يختلط =" noreferrer نوفولو "> أزواج بديلة بعين الاعتبار. رأيت أيضا codepoints %hh مختلطة، على سبيل الارتباك المضافة.

ومع أخذ ذلك في الاعتبار، وهنا هو فك التي تعمل في كل من بايثون 2 و 3 بيثون، شريطة أن تمر في كائن str في بيثون 3 (بايثون 2 يهتم أقل):

try:
    # Python 3
    from urllib.parse import unquote
    unichr = chr
except ImportError:
    # Python 2
    from urllib import unquote

def unquote_unicode(string, _cache={}):
    string = unquote(string)  # handle two-digit %hh components first
    parts = string.split(u'%u')
    if len(parts) == 1:
        return parts
    r = [parts[0]]
    append = r.append
    for part in parts[1:]:
        try:
            digits = part[:4].lower()
            if len(digits) < 4:
                raise ValueError
            ch = _cache.get(digits)
            if ch is None:
                ch = _cache[digits] = unichr(int(digits, 16))
            if (
                not r[-1] and
                u'\uDC00' <= ch <= u'\uDFFF' and
                u'\uD800' <= r[-2] <= u'\uDBFF'
            ):
                # UTF-16 surrogate pair, replace with single non-BMP codepoint
                r[-2] = (r[-2] + ch).encode(
                    'utf-16', 'surrogatepass').decode('utf-16')
            else:
                append(ch)
            append(part[4:])
        except ValueError:
            append(u'%u')
            append(part)
    return u''.join(r)

وظيفة مستوحى بشكل كبير من قبل متداولة مكتبة مستوى تنفيذ .

وعرض توضيحي:

>>> print(unquote_unicode('Tan%u0131m'))
Tanım
>>> print(unquote_unicode('%u05D0%u05D9%u05DA%20%u05DE%u05DE%u05D9%u05E8%u05D9%u05DD%20%u05D0%u05EA%20%u05D4%u05D8%u05E7%u05E1%u05D8%20%u05D4%u05D6%u05D4'))
איך ממירים את הטקסט הזה
>>> print(unquote_unicode('%ud83c%udfd6'))  # surrogate pair
🏖
>>> print(unquote_unicode('%ufoobar%u666'))  # incomplete
%ufoobar%u666

وتعمل وظيفة على بايثون 2 (اختبار على 2،4-2،7) وبيثون 3 (اختبار على 3،3-3،8).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top