Hướng dẫn â€tm instead of python - â€tm thay vì trăn

Vấn đề của bạn là dấu nháy đơn đang bị hiểu sai không phải là một ký tự dấu nháy đơn bình thường ' mà thay vào đó là ký tự Unicode cho một trích dẫn đơn phải: . Lý do nó biến thành Mojibake là vì bạn đang giải mã nội dung không chính xác. Đó là trong UTF-8 (vì vậy được đại diện bởi ba byte \xe2\x80\x99), nhưng bạn đang giải mã nó bằng codePage 1252 (trong đó ba byte \xe2\x80\x99 đại diện cho ba ký tự riêng biệt, â,

# A table telling us how to interpret the first word of a letter's Unicode
# name. The number indicates how frequently we expect this script to be used
# on computers. Many scripts not included here are assumed to have a frequency
# of "0" -- if you're going to write in Linear B using Unicode, you're
# probably aware enough of encoding issues to get it right.
#
# The lowercase name is a general category -- for example, Han characters and
# Hiragana characters are very frequently adjacent in Japanese, so they all go
# into category 'cjk'. Letters of different categories are assumed not to
# appear next to each other often.
SCRIPT_TABLE = {
    'LATIN': (3, 'latin'),
    'CJK': (2, 'cjk'),
    'ARABIC': (2, 'arabic'),
    'CYRILLIC': (2, 'cyrillic'),
    'GREEK': (2, 'greek'),
    'HEBREW': (2, 'hebrew'),
    'KATAKANA': (2, 'cjk'),
    'HIRAGANA': (2, 'cjk'),
    'HIRAGANA-KATAKANA': (2, 'cjk'),
    'HANGUL': (2, 'cjk'),
    'DEVANAGARI': (2, 'devanagari'),
    'THAI': (2, 'thai'),
    'FULLWIDTH': (2, 'cjk'),
    'MODIFIER': (2, None),
    'HALFWIDTH': (1, 'cjk'),
    'BENGALI': (1, 'bengali'),
    'LAO': (1, 'lao'),
    'KHMER': (1, 'khmer'),
    'TELUGU': (1, 'telugu'),
    'MALAYALAM': (1, 'malayalam'),
    'SINHALA': (1, 'sinhala'),
    'TAMIL': (1, 'tamil'),
    'GEORGIAN': (1, 'georgian'),
    'ARMENIAN': (1, 'armenian'),
    'KANNADA': (1, 'kannada'),  # mostly used for looks of disapproval
    'MASCULINE': (1, 'latin'),
    'FEMININE': (1, 'latin')
}
0 và
# A table telling us how to interpret the first word of a letter's Unicode
# name. The number indicates how frequently we expect this script to be used
# on computers. Many scripts not included here are assumed to have a frequency
# of "0" -- if you're going to write in Linear B using Unicode, you're
# probably aware enough of encoding issues to get it right.
#
# The lowercase name is a general category -- for example, Han characters and
# Hiragana characters are very frequently adjacent in Japanese, so they all go
# into category 'cjk'. Letters of different categories are assumed not to
# appear next to each other often.
SCRIPT_TABLE = {
    'LATIN': (3, 'latin'),
    'CJK': (2, 'cjk'),
    'ARABIC': (2, 'arabic'),
    'CYRILLIC': (2, 'cyrillic'),
    'GREEK': (2, 'greek'),
    'HEBREW': (2, 'hebrew'),
    'KATAKANA': (2, 'cjk'),
    'HIRAGANA': (2, 'cjk'),
    'HIRAGANA-KATAKANA': (2, 'cjk'),
    'HANGUL': (2, 'cjk'),
    'DEVANAGARI': (2, 'devanagari'),
    'THAI': (2, 'thai'),
    'FULLWIDTH': (2, 'cjk'),
    'MODIFIER': (2, None),
    'HALFWIDTH': (1, 'cjk'),
    'BENGALI': (1, 'bengali'),
    'LAO': (1, 'lao'),
    'KHMER': (1, 'khmer'),
    'TELUGU': (1, 'telugu'),
    'MALAYALAM': (1, 'malayalam'),
    'SINHALA': (1, 'sinhala'),
    'TAMIL': (1, 'tamil'),
    'GEORGIAN': (1, 'georgian'),
    'ARMENIAN': (1, 'armenian'),
    'KANNADA': (1, 'kannada'),  # mostly used for looks of disapproval
    'MASCULINE': (1, 'latin'),
    'FEMININE': (1, 'latin')
}
1).

Vì bạn chưa hiển thị nhiều mã, tôi không thể đưa ra bất kỳ đề xuất nào về cách khắc phục sự cố giải mã, nhưng có lẽ có cách yêu cầu Selenium sử dụng UTF-8 (tôi thực sự ngạc nhiên là mặc định). Ngoài ra, bạn có thể có được các byte thô và tự giải mã văn bản.

Mặc dù tốt nhất là tránh việc mã hóa sai, nhưng nếu bạn thực sự cần sửa các chuỗi của mình sau khi chúng được chuyển sang Mojibake, thì cách tiếp cận tốt nhất có lẽ là để mã hóa lại chúng giống như cách chúng được mã hóa sai, sau đó Giải mã lại, chính xác lần này:

badtext = 'America’s'
encoded = badtext.encode('cp1252') 
goodtext = encoded.decode('utf-8') # 'America’s'

CẬP NHẬT: Bạn không chỉ có thể sửa lỗi Unicode với Python, bạn còn có thể sửa lỗi của Unicode với gói Python nguồn mở của chúng tôi, FTFY. Not only can you fix Unicode mistakes with Python, you can fix Unicode mistakes with our open source Python package, “ftfy”.

Bạn gần như chắc chắn đã thấy văn bản trên một máy tính trông giống như & nbsp; cái này:

Nếu các số không đẹp, tôi không biết là gì. â € Paul Paul & nbsp; erdå

Ở đâu đó, một máy tính đã nắm giữ một danh sách các số được dự định tạo thành một trích dẫn và đã làm một cái gì đó rõ ràng không đẹp mắt với nó. Một người đọc có thể suy luận rằng nó thực sự được cho là nói & nbsp; điều này:

Nếu những con số aren đẹp, tôi không biết là gì. Mạnhpaul & nbsp; erdős

Ở đây, những gì mà xảy ra. Một máy tính hiện đại có khả năng hiển thị văn bản sử dụng hơn 100.000 ký tự khác nhau, nhưng thật không may, văn bản đôi khi đi qua một chương trình cũ đáng tin cậy tin rằng chỉ có 256 rằng nó có thể phù hợp với một byte duy nhất. Chương trình không thậm chí còn bận tâm để kiểm tra mã hóa văn bản là gì; Nó chỉ sử dụng mã hóa yêu thích của riêng mình và biến một loạt các ký tự thành các chuỗi hoàn toàn khác nhau & nbsp; các ký tự.

Bây giờ, bạn không phải là lập trình viên gây ra các vấn đề mã hóa, phải không? Bởi vì bạn đã đọc một cái gì đó như Joel Spolsky, mức tối thiểu tuyệt đối mà mọi nhà phát triển hoàn toàn, tích cực phải biết về các bộ unicode và nhân vật hoặc python unicode howto và bạn đã học được sự khác biệt giữa văn bản và bytestrings và cách nhận chúng.HOWTO and you’ve learned the difference between text and bytestrings and how to get them right.

Nhưng vấn đề là đôi khi bạn có thể phải xử lý văn bản xuất phát từ mã khác. Chúng tôi đối phó với điều này rất nhiều tại Luminoso, nơi văn bản mà khách hàng của chúng tôi muốn chúng tôi phân tích thường được chuyển qua một số phần mềm khác nhau, mỗi phần có những điều kỳ quặc của riêng họ, có thể với Microsoft Office ở đâu đó trong chuỗi & nbsp;

Vì vậy, bài đăng này không phải là về cách làm đúng. Nó nói về một công cụ mà chúng tôi đã đưa ra để kiểm soát thiệt hại sau khi một số chương trình khác không sai. Nó phát hiện một số lỗi mã hóa phổ biến nhất và làm những gì có thể để hoàn tác & nbsp; chúng.

Ở đây, loại sai lầm của Unicode mà chúng tôi đã sửa lỗi.

  • Một số văn bản, ở đâu đó, được mã hóa thành byte bằng UTF-8 (nhanh chóng trở thành mã hóa tiêu chuẩn cho văn bản trên & NBSP; Internet).UTF-8 (which is quickly becoming the standard encoding for text on the Internet).
  • Phần mềm nhận được văn bản này không phải là UTF-8. Thay vào đó, nó giải mã các byte trong một mã hóa chỉ với 256 ký tự. Đơn giản nhất trong số các mã hóa này là bộ mã được gọi là ISO-8859-1, hay Lat Latin-1 trong số những người bạn. Trong Latin-1, bạn ánh xạ 256 byte có thể cho 256 ký tự Unicode đầu tiên. Mã hóa này có thể phát sinh một cách tự nhiên từ phần mềm mà thậm chí không xem xét rằng các mã hóa khác nhau & nbsp; tồn tại.UTF-8. It instead decodes the bytes in an encoding with only 256 characters. The simplest of these encodings is the one called “ISO-8859-1”, or “Latin-1” among friends. In Latin-1, you map the 256 possible bytes to the first 256 Unicode characters. This encoding can arise naturally from software that doesn’t even consider that different encodings exist.
  • Kết quả là mọi nhân vật không phải ASCII đều biến thành hai hoặc ba ký tự rác & nbsp;ASCII character turns into two or three garbage characters.

Ba codec được kiểm soát phổ biến nhất là UTF-8, Latin-1 và Windows-1252. Có rất nhiều codec khác được sử dụng trên thế giới, nhưng chúng rõ ràng là rất khác với ba code này đến nỗi mọi người đều có thể nói khi họ đã sai. Chúng tôi sẽ tập trung vào việc sửa chữa các trường hợp trong đó văn bản được mã hóa là một trong ba codec này và được giải mã AS & nbsp; khác.UTF-8, Latin-1, and Windows-1252. There are lots of other codecs in use in the world, but they are so obviously different from these three that everyone can tell when they’ve gone wrong. We’ll focus on fixing cases where text was encoded as one of these three codecs and decoded as another.

Đầu tiên & nbsp; cố gắng thánh

Khi bạn nhìn vào loại rác mà Lừa được sản xuất bởi quá trình này, các chuỗi nhân vật có vẻ rất xấu xí và vô nghĩa đến nỗi bạn có thể thay thế bất cứ thứ gì trông giống như nó phải là UTF-8. Chỉ cần tìm các chuỗi đó, thay thế chúng vô điều kiện bằng những gì chúng sẽ ở UTF-8 và bạn đã hoàn thành. Trên thực tế, đó là những gì phiên bản đầu tiên của tôi đã làm. Bỏ qua một loạt các trường hợp cạnh và xử lý lỗi, nó trông giống như & nbsp; cái này:UTF-8. Just find those sequences, replace them unconditionally with what they would be in UTF-8, and you’re done. In fact, that’s what my first version did. Skipping a bunch of edge cases and error handling, it looked something like this:

# A table telling us how to interpret the first word of a letter's Unicode
# name. The number indicates how frequently we expect this script to be used
# on computers. Many scripts not included here are assumed to have a frequency
# of "0" -- if you're going to write in Linear B using Unicode, you're
# probably aware enough of encoding issues to get it right.
#
# The lowercase name is a general category -- for example, Han characters and
# Hiragana characters are very frequently adjacent in Japanese, so they all go
# into category 'cjk'. Letters of different categories are assumed not to
# appear next to each other often.
SCRIPT_TABLE = {
    'LATIN': (3, 'latin'),
    'CJK': (2, 'cjk'),
    'ARABIC': (2, 'arabic'),
    'CYRILLIC': (2, 'cyrillic'),
    'GREEK': (2, 'greek'),
    'HEBREW': (2, 'hebrew'),
    'KATAKANA': (2, 'cjk'),
    'HIRAGANA': (2, 'cjk'),
    'HIRAGANA-KATAKANA': (2, 'cjk'),
    'HANGUL': (2, 'cjk'),
    'DEVANAGARI': (2, 'devanagari'),
    'THAI': (2, 'thai'),
    'FULLWIDTH': (2, 'cjk'),
    'MODIFIER': (2, None),
    'HALFWIDTH': (1, 'cjk'),
    'BENGALI': (1, 'bengali'),
    'LAO': (1, 'lao'),
    'KHMER': (1, 'khmer'),
    'TELUGU': (1, 'telugu'),
    'MALAYALAM': (1, 'malayalam'),
    'SINHALA': (1, 'sinhala'),
    'TAMIL': (1, 'tamil'),
    'GEORGIAN': (1, 'georgian'),
    'ARMENIAN': (1, 'armenian'),
    'KANNADA': (1, 'kannada'),  # mostly used for looks of disapproval
    'MASCULINE': (1, 'latin'),
    'FEMININE': (1, 'latin')
}

Một unicode thông minh & nbsp; fixer¶

Bởi vì văn bản được mã hóa thực sự có thể mơ hồ, chúng ta phải tìm hiểu xem văn bản tốt hơn khi chúng ta sửa nó hay khi chúng ta để nó một mình. Mark Pilgrim đáng kính có cái nhìn sâu sắc quan trọng khi thảo luận về Chardet & NBSP; Mô -đun:

Phát hiện mã hóa thực sự là phát hiện ngôn ngữ trong lực cản. Đoạn Pilgrim, đi sâu vào Python & NBSP; 3

Lý do từ ngữ bront 녔 녔 rất sai là vì năm ký tự đầu tiên là các chữ cái La Mã, trong khi bản cuối cùng là Hangul, và hầu hết các từ trong hầu hết các ngôn ngữ đều không trộn lẫn hai tập lệnh khác nhau như & nbsp;

Đây là nơi thư viện tiêu chuẩn Python bắt đầu tỏa sáng. & NBSP; Mô -đun

# A table telling us how to interpret the first word of a letter's Unicode
# name. The number indicates how frequently we expect this script to be used
# on computers. Many scripts not included here are assumed to have a frequency
# of "0" -- if you're going to write in Linear B using Unicode, you're
# probably aware enough of encoding issues to get it right.
#
# The lowercase name is a general category -- for example, Han characters and
# Hiragana characters are very frequently adjacent in Japanese, so they all go
# into category 'cjk'. Letters of different categories are assumed not to
# appear next to each other often.
SCRIPT_TABLE = {
    'LATIN': (3, 'latin'),
    'CJK': (2, 'cjk'),
    'ARABIC': (2, 'arabic'),
    'CYRILLIC': (2, 'cyrillic'),
    'GREEK': (2, 'greek'),
    'HEBREW': (2, 'hebrew'),
    'KATAKANA': (2, 'cjk'),
    'HIRAGANA': (2, 'cjk'),
    'HIRAGANA-KATAKANA': (2, 'cjk'),
    'HANGUL': (2, 'cjk'),
    'DEVANAGARI': (2, 'devanagari'),
    'THAI': (2, 'thai'),
    'FULLWIDTH': (2, 'cjk'),
    'MODIFIER': (2, None),
    'HALFWIDTH': (1, 'cjk'),
    'BENGALI': (1, 'bengali'),
    'LAO': (1, 'lao'),
    'KHMER': (1, 'khmer'),
    'TELUGU': (1, 'telugu'),
    'MALAYALAM': (1, 'malayalam'),
    'SINHALA': (1, 'sinhala'),
    'TAMIL': (1, 'tamil'),
    'GEORGIAN': (1, 'georgian'),
    'ARMENIAN': (1, 'armenian'),
    'KANNADA': (1, 'kannada'),  # mostly used for looks of disapproval
    'MASCULINE': (1, 'latin'),
    'FEMININE': (1, 'latin')
}
2 có thể cho chúng tôi biết rất nhiều điều chúng tôi muốn biết về bất kỳ & nbsp;

>>> import unicodedata
>>> unicodedata.category(u't')
'Ll'
>>> unicodedata.name(u't')
'LATIN SMALL LETTER T'
>>> unicodedata.category(u'녔')
'Lo'
>>> unicodedata.name(u'녔')
'HANGUL SYLLABLE NYEOSS'

Bây giờ chúng ta có thể viết một trình sửa chữa unicode phức tạp hơn nhưng nguyên tắc hơn nhiều bằng cách tuân theo một số quy tắc của & nbsp; ngón tay cái:

  • Chúng tôi muốn áp dụng một phép biến đổi nhất quán giúp giảm thiểu số lượng những điều kỳ lạ mà xảy ra trong chuỗi A & nbsp;
  • Các ký tự đơn lẻ tối nghĩa, chẳng hạn như ¶ và, là & nbsp; kỳ lạ.
  • Các biểu tượng toán học và tiền tệ liền kề với các biểu tượng khác là & nbsp; kỳ lạ.
  • Có hai chữ cái liền kề từ các tập lệnh khác nhau là rất & nbsp; kỳ lạ.
  • Gây ra các lỗi giải mã mới mà biến các ký tự bình thường thành � là không thể chấp nhận được và nên đếm nhiều hơn bất kỳ vấn đề nào khác & nbsp;
  • Ưu tiên các chuỗi ngắn hơn so với các chuỗi dài hơn, miễn là chuỗi ngắn hơn là & nbsp; Weirder.
  • Ước tính được mã hóa chính xác Windows-1252 Gremlins trên các loại được mã hóa không chính xác & nbsp;

Điều đó dẫn chúng ta đến một trình sửa chữa unicode hoàn chỉnh áp dụng các quy tắc này. Nó thực hiện một công việc tuyệt vời trong việc sửa chữa các tập tin chứa đầy từng dòng, chẳng hạn như danh sách tần số tiếng Tây Ban Nha của Đại học Leeds Unicode không chính xác trên & nbsp; web.

Mã chúng tôi đến xuất hiện dưới đây. (Nhưng khi tôi chỉnh sửa bài đăng này sáu năm sau, tôi nên nhắc nhở bạn rằng đây là năm 2012!

# -*- coding: utf-8 -*-
#
# This code has become part of the "ftfy" library:
#
# http://ftfy.readthedocs.io/en/latest/
#
# That library is actively maintained and works on Python 2 or 3. This recipe
# is not.

import unicodedata

def fix_bad_unicode(text):
    u"""
    Something you will find all over the place, in real-world text, is text
    that's mistakenly encoded as utf-8, decoded in some ugly format like
    latin-1 or even Windows codepage 1252, and encoded as utf-8 again.

    This causes your perfectly good Unicode-aware code to end up with garbage
    text because someone else (or maybe "someone else") made a mistake.

    This function looks for the evidence of that having happened and fixes it.
    It determines whether it should replace nonsense sequences of single-byte
    characters that were really meant to be UTF-8 characters, and if so, turns
    them into the correctly-encoded Unicode character that they were meant to
    represent.

    The input to the function must be Unicode. It's not going to try to
    auto-decode bytes for you -- then it would just create the problems it's
    supposed to fix.

        >>> print fix_bad_unicode(u'único')
        único

        >>> print fix_bad_unicode(u'This text is fine already :þ')
        This text is fine already :þ

    Because these characters often come from Microsoft products, we allow
    for the possibility that we get not just Unicode characters 128-255, but
    also Windows's conflicting idea of what characters 128-160 are.

        >>> print fix_bad_unicode(u'This — should be an em dash')
        This — should be an em dash

    We might have to deal with both Windows characters and raw control
    characters at the same time, especially when dealing with characters like
    \x81 that have no mapping in Windows.

        >>> print fix_bad_unicode(u'This text is sad .â\x81”.')
        This text is sad .⁔.

    This function even fixes multiple levels of badness:

        >>> wtf = u'\xc3\xa0\xc2\xb2\xc2\xa0_\xc3\xa0\xc2\xb2\xc2\xa0'
        >>> print fix_bad_unicode(wtf)
        ಠ_ಠ

    However, it has safeguards against fixing sequences of letters and
    punctuation that can occur in valid text:

        >>> print fix_bad_unicode(u'not such a fan of Charlotte Brontë…”')
        not such a fan of Charlotte Brontë…”

    Cases of genuine ambiguity can sometimes be addressed by finding other
    characters that are not double-encoding, and expecting the encoding to
    be consistent:

        >>> print fix_bad_unicode(u'AHÅ™, the new sofa from IKEA®')
        AHÅ™, the new sofa from IKEA®

    Finally, we handle the case where the text is in a single-byte encoding
    that was intended as Windows-1252 all along but read as Latin-1:

        >>> print fix_bad_unicode(u'This text was never Unicode at all\x85')
        This text was never Unicode at all…
    """
    if not isinstance(text, unicode):
        raise TypeError("This isn't even decoded into Unicode yet. "
                        "Decode it first.")
    if len(text) == 0:
        return text

    maxord = max(ord(char) for char in text)
    tried_fixing = []
    if maxord < 128:
        # Hooray! It's ASCII!
        return text
    else:
        attempts = [(text, text_badness(text) + len(text))]
        if maxord < 256:
            tried_fixing = reinterpret_latin1_as_utf8(text)
            tried_fixing2 = reinterpret_latin1_as_windows1252(text)
            attempts.append((tried_fixing, text_cost(tried_fixing)))
            attempts.append((tried_fixing2, text_cost(tried_fixing2)))
        elif all(ord(char) in WINDOWS_1252_CODEPOINTS for char in text):
            tried_fixing = reinterpret_windows1252_as_utf8(text)
            attempts.append((tried_fixing, text_cost(tried_fixing)))
        else:
            # We can't imagine how this would be anything but valid text.
            return text

        # Sort the results by badness
        attempts.sort(key=lambda x: x[1])
        #print attempts
        goodtext = attempts[0][0]
        if goodtext == text:
            return goodtext
        else:
            return fix_bad_unicode(goodtext)


def reinterpret_latin1_as_utf8(wrongtext):
    newbytes = wrongtext.encode('latin-1', 'replace')
    return newbytes.decode('utf-8', 'replace')


def reinterpret_windows1252_as_utf8(wrongtext):
    altered_bytes = []
    for char in wrongtext:
        if ord(char) in WINDOWS_1252_GREMLINS:
            altered_bytes.append(char.encode('WINDOWS_1252'))
        else:
            altered_bytes.append(char.encode('latin-1', 'replace'))
    return ''.join(altered_bytes).decode('utf-8', 'replace')


def reinterpret_latin1_as_windows1252(wrongtext):
    """
    Maybe this was always meant to be in a single-byte encoding, and it
    makes the most sense in Windows-1252.
    """
    return wrongtext.encode('latin-1').decode('WINDOWS_1252', 'replace')


def text_badness(text):
    u'''
    Look for red flags that text is encoded incorrectly:

    Obvious problems:
    - The replacement character \ufffd, indicating a decoding error
    - Unassigned or private-use Unicode characters

    Very weird things:
    - Adjacent letters from two different scripts
    - Letters in scripts that are very rarely used on computers (and
      therefore, someone who is using them will probably get Unicode right)
    - Improbable control characters, such as 0x81

    Moderately weird things:
    - Improbable single-byte characters, such as ƒ or ¬
    - Letters in somewhat rare scripts
    '''
    assert isinstance(text, unicode)
    errors = 0
    very_weird_things = 0
    weird_things = 0
    prev_letter_script = None
    for pos in xrange(len(text)):
        char = text[pos]
        index = ord(char)
        if index < 256:
            # Deal quickly with the first 256 characters.
            weird_things += SINGLE_BYTE_WEIRDNESS[index]
            if SINGLE_BYTE_LETTERS[index]:
                prev_letter_script = 'latin'
            else:
                prev_letter_script = None
        else:
            category = unicodedata.category(char)
            if category == 'Co':
                # Unassigned or private use
                errors += 1
            elif index == 0xfffd:
                # Replacement character
                errors += 1
            elif index in WINDOWS_1252_GREMLINS:
                lowchar = char.encode('WINDOWS_1252').decode('latin-1')
                weird_things += SINGLE_BYTE_WEIRDNESS[ord(lowchar)] - 0.5

            if category.startswith('L'):
                # It's a letter. What kind of letter? This is typically found
                # in the first word of the letter's Unicode name.
                name = unicodedata.name(char)
                scriptname = name.split()[0]
                freq, script = SCRIPT_TABLE.get(scriptname, (0, 'other'))
                if prev_letter_script:
                    if script != prev_letter_script:
                        very_weird_things += 1
                    if freq == 1:
                        weird_things += 2
                    elif freq == 0:
                        very_weird_things += 1
                prev_letter_script = script
            else:
                prev_letter_script = None

    return 100 * errors + 10 * very_weird_things + weird_things


def text_cost(text):
    """
    Assign a cost function to the length plus weirdness of a text string.
    """
    return text_badness(text) + len(text)

#######################################################################
# The rest of this file is esoteric info about characters, scripts, and their
# frequencies.
#
# Start with an inventory of "gremlins", which are characters from all over
# Unicode that Windows has instead assigned to the control characters
# 0x80-0x9F. We might encounter them in their Unicode forms and have to figure
# out what they were originally.

WINDOWS_1252_GREMLINS = [
    # adapted from http://effbot.org/zone/unicode-gremlins.htm
    0x0152,  # LATIN CAPITAL LIGATURE OE
    0x0153,  # LATIN SMALL LIGATURE OE
    0x0160,  # LATIN CAPITAL LETTER S WITH CARON
    0x0161,  # LATIN SMALL LETTER S WITH CARON
    0x0178,  # LATIN CAPITAL LETTER Y WITH DIAERESIS
    0x017E,  # LATIN SMALL LETTER Z WITH CARON
    0x017D,  # LATIN CAPITAL LETTER Z WITH CARON
    0x0192,  # LATIN SMALL LETTER F WITH HOOK
    0x02C6,  # MODIFIER LETTER CIRCUMFLEX ACCENT
    0x02DC,  # SMALL TILDE
    0x2013,  # EN DASH
    0x2014,  # EM DASH
    0x201A,  # SINGLE LOW-9 QUOTATION MARK
    0x201C,  # LEFT DOUBLE QUOTATION MARK
    0x201D,  # RIGHT DOUBLE QUOTATION MARK
    0x201E,  # DOUBLE LOW-9 QUOTATION MARK
    0x2018,  # LEFT SINGLE QUOTATION MARK
    0x2019,  # RIGHT SINGLE QUOTATION MARK
    0x2020,  # DAGGER
    0x2021,  # DOUBLE DAGGER
    0x2022,  # BULLET
    0x2026,  # HORIZONTAL ELLIPSIS
    0x2030,  # PER MILLE SIGN
    0x2039,  # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
    0x203A,  # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
    0x20AC,  # EURO SIGN
    0x2122,  # TRADE MARK SIGN
]

# a list of Unicode characters that might appear in Windows-1252 text
WINDOWS_1252_CODEPOINTS = range(256) + WINDOWS_1252_GREMLINS

# Rank the characters typically represented by a single byte -- that is, in
# Latin-1 or Windows-1252 -- by how weird it would be to see them in running
# text.
#
#   0 = not weird at all
#   1 = rare punctuation or rare letter that someone could certainly
#       have a good reason to use. All Windows-1252 gremlins are at least
#       weirdness 1.
#   2 = things that probably don't appear next to letters or other
#       symbols, such as math or currency symbols
#   3 = obscure symbols that nobody would go out of their way to use
#       (includes symbols that were replaced in ISO-8859-15)
#   4 = why would you use this?
#   5 = unprintable control character
#
# The Portuguese letter à (0xc3) is marked as weird because it would usually
# appear in the middle of a word in actual Portuguese, and meanwhile it
# appears in the mis-encodings of many common characters.

SINGLE_BYTE_WEIRDNESS = (
#   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5,  # 0x00
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,  # 0x10
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x20
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x30
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x40
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x50
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0x60
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,  # 0x70
    2, 5, 1, 4, 1, 1, 3, 3, 4, 3, 1, 1, 1, 5, 1, 5,  # 0x80
    5, 1, 1, 1, 1, 3, 1, 1, 4, 1, 1, 1, 1, 5, 1, 1,  # 0x90
    1, 0, 2, 2, 3, 2, 4, 2, 4, 2, 2, 0, 3, 1, 1, 4,  # 0xa0
    2, 2, 3, 3, 4, 3, 3, 2, 4, 4, 4, 0, 3, 3, 3, 0,  # 0xb0
    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xc0
    1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xd0
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xe0
    1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,  # 0xf0
)

# Pre-cache the Unicode data saying which of these first 256 characters are
# letters. We'll need it often.
SINGLE_BYTE_LETTERS = [
    unicodedata.category(unichr(i)).startswith('L')
    for i in xrange(256)
]

# A table telling us how to interpret the first word of a letter's Unicode
# name. The number indicates how frequently we expect this script to be used
# on computers. Many scripts not included here are assumed to have a frequency
# of "0" -- if you're going to write in Linear B using Unicode, you're
# you're probably aware enough of encoding issues to get it right.
#
# The lowercase name is a general category -- for example, Han characters and
# Hiragana characters are very frequently adjacent in Japanese, so they all go
# into category 'cjk'. Letters of different categories are assumed not to
# appear next to each other often.
SCRIPT_TABLE = {
    'LATIN': (3, 'latin'),
    'CJK': (2, 'cjk'),
    'ARABIC': (2, 'arabic'),
    'CYRILLIC': (2, 'cyrillic'),
    'GREEK': (2, 'greek'),
    'HEBREW': (2, 'hebrew'),
    'KATAKANA': (2, 'cjk'),
    'HIRAGANA': (2, 'cjk'),
    'HIRAGANA-KATAKANA': (2, 'cjk'),
    'HANGUL': (2, 'cjk'),
    'DEVANAGARI': (2, 'devanagari'),
    'THAI': (2, 'thai'),
    'FULLWIDTH': (2, 'cjk'),
    'MODIFIER': (2, None),
    'HALFWIDTH': (1, 'cjk'),
    'BENGALI': (1, 'bengali'),
    'LAO': (1, 'lao'),
    'KHMER': (1, 'khmer'),
    'TELUGU': (1, 'telugu'),
    'MALAYALAM': (1, 'malayalam'),
    'SINHALA': (1, 'sinhala'),
    'TAMIL': (1, 'tamil'),
    'GEORGIAN': (1, 'georgian'),
    'ARMENIAN': (1, 'armenian'),
    'KANNADA': (1, 'kannada'),  # mostly used for looks of disapproval
    'MASCULINE': (1, 'latin'),
    'FEMININE': (1, 'latin')
}

Bạn có thể sử dụng Unicode trong Python không?

Loại chuỗi của Python sử dụng tiêu chuẩn Unicode để biểu diễn các ký tự, cho phép các chương trình Python hoạt động với tất cả các ký tự có thể khác nhau này., which lets Python programs work with all these different possible characters.

Unicode Escape Python là gì?

Các trình xử lý này được gọi bất cứ khi nào một vấn đề hoặc lỗi xảy ra trong quá trình mã hóa hoặc giải mã chuỗi hoặc văn bản đã cho.Để bao gồm các ký tự Unicode trong chương trình Python, trước tiên chúng tôi sử dụng ký hiệu Escape Unicode \ u trước bất kỳ chuỗi nào, có thể được coi là biến loại Unicode.invoked whenever a problem or error occurs in the process of encoding or decoding the string or given text. To include Unicode characters in the Python program, we first use Unicode escape symbol \u before any string, which can be considered as a Unicode-type variable.

Mã hóa Python là gì?

Vì Python 3.0, các chuỗi được lưu trữ dưới dạng unicode, tức là mỗi ký tự trong chuỗi được biểu thị bằng một điểm mã.Vì vậy, mỗi chuỗi chỉ là một chuỗi các điểm mã Unicode.Để lưu trữ hiệu quả các chuỗi này, chuỗi các điểm mã được chuyển đổi thành một tập hợp các byte.Quá trình được gọi là mã hóa.the sequence of code points is converted into a set of bytes. The process is known as encoding.