[PYTHON] Der Rückgabewert von len oder unichr kann sich ändern, je nachdem, ob es sich um UCS-2 oder UCS-4 handelt.

Das Standard-Python 2 von Mac OS X basiert auf UCS-2, daher unterscheiden sich die von den Standardfunktionen len und unichr zurückgegebenen Werte von denen in UCS-4, das in der Linux-Distribution weit verbreitet ist. Es gibt.

Verhalten in UCS-2-Erstellungsoptionen

Wenn die Build-Option UCS-2 ist und U + 10000 und nachfolgende Zeichen enthält, kann len nicht so verwendet werden, wie es ist, um die Anzahl der Zeichen zu bestimmen. Selbst wenn es von Homebrew installiert wird, wird es von USC-2 gebaut.

Verwenden Sie den Wert von sys.maxunicode, um festzustellen, ob UCS-2 für die Erstellungsoption angegeben wurde.

>>> import sys
>>> 0xFFFF == sys.maxunicode
True

Das Anwenden von len auf die folgende Zeichenfolge (U + 20BB7 U + 91CE U + 5BB6) führt zu einem Rückgabewert von 4.

>>> str = u'?Noya'
>>> 4 == len(str)
True

Die interne Darstellung von U + 20BB7 ist das Ersatzpaar U + D842 U + DFB7.

>>> 0xD842 == ord(str[0])
True
>>> 0xDFB7 == ord(str[1])
True

Finden Sie die Anzahl der Zeichen unter Berücksichtigung von UCS-2

Lassen Sie uns die Anzahl der Zeichen ermitteln, wenn man bedenkt, dass der Bereich des oberen Ersatzes von U + D800 bis U + DBFF reicht. Berücksichtigen Sie der Einfachheit halber keine Fälle, in denen der obere oder untere Ersatz isoliert ist. Mit UCS-4 können Sie for-Schleifen verwenden.

# -*- coding: utf-8 -*-

import sys

def utf8_len(str):

    length = 0

    if sys.maxunicode > 0xFFFF:
        for c in str:
            length += 1

        return length

    code_units = len(str)
    pos = 0
    cp = -1

    while pos < code_units:

        cp = ord(str[pos])
        length += 1

        if cp > 0xD7FF and 0xDC00 > cp:
            pos += 2
        else:
            pos += 1

    return length

Versuchen wir es noch einmal mit der vorherigen Zeichenfolge.

str = u'?Noya'
print(3 == utf8_len(str))

Als Übung ändern wir den Code ein wenig und definieren eine Funktion, die Rückrufe Zeichen für Zeichen anwendet.

# -*- coding: utf-8 -*-

import sys

def utf8_each_char(str, func):

    if sys.maxunicode > 0xFFFF:
        for c in str:
            func(c)
    else:
        code_units = len(str)
        pos = 0
        buf = ''
        cp = -1

    while pos < code_units:
        buf =str[pos]
        cp = ord(buf)

        if cp > 0xD7FF and 0xDC00 > cp:
            buf += str[pos+1]
            func(buf)
            pos += 2
        else:
            func(buf)
            pos += 1

Lassen Sie uns jeweils ein Zeichen anzeigen. Um print mit einem Lambda-Ausdruck zu verwenden, müssen Sie print_function am Anfang der Datei importieren.

from __future__ import print_function

str = u'?Noya'
f = lambda c: print(c)
utf8_each_char(str, f)

Generieren Sie Zeichen aus Codepunkten unter Berücksichtigung von UCS-2

Die USC-2-Einschränkung akzeptiert auch unichr, das Zeichen aus Codepunkt-Ganzzahlen generiert, und akzeptiert keine 0x10000 und nachfolgende Ganzzahlen.

>>> unichr(0x20BB7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unichr() arg not in range(0x10000) (narrow Python build)

Unicode-Escape-Sequenzen sind von UCS-2 nicht betroffen.


>>> print(u"\U00020BB7")
?

Das Folgende ist eine Definition einer Benutzerfunktion, die die Einschränkungen von UCS-2 berücksichtigt.

# -*- coding: utf-8 -*-

import sys

def utf8_chr(cp):
    if 0xFFFF < sys.maxunicode or cp < 0x10000:
        return unichr(cp)

    cp -= 0x10000
    high = cp >> 10 | 0xD800
    low = cp & 0x3FF | 0xDC00

    return unichr(high) + unichr(low)

print(utf8_chr(0x20BB7))
print(utf8_chr(0x91CE))

Recommended Posts

Der Rückgabewert von len oder unichr kann sich ändern, je nachdem, ob es sich um UCS-2 oder UCS-4 handelt.
Ändern Sie in Python das Verhalten der Methode je nach Aufruf
Achten Sie auf den Rückgabewert von __len__
Ein einfacher Grund, warum der Rückgabewert von round (2.675,2) in Python 2,67 beträgt (in Wirklichkeit sollte er 2,68 betragen ...)
Über den Rückgabewert von pthread_mutex_init ()
Über den Rückgabewert des Histogramms.
Grundtechnologie, die leicht feststellt, ob der Wert "Ja" oder "Nein" ist
Lassen Sie uns das Farbschema von iTerm2 je nach Tageszeit automatisch ändern
Ändern Sie die Reihenfolge von PostgreSQL in Heroku
Wie sich die Referenz des Python-Arrays ändert, hängt vom Vorhandensein oder Fehlen von Indizes ab
Wenn verzweigen, hängt davon ab, ob die Liste ein bestimmtes Element enthält
Der Wert von pyTorch torch.var () wird nicht verteilt
Ändern Sie die Auflösung von Ubuntu, das auf VirtualBox ausgeführt wird
[Python Data Frame] Wenn der Wert leer ist, füllen Sie ihn mit dem Wert einer anderen Spalte.
Rückgabewert von quit () - Gibt es etwas, das von der "Funktion, die alles beendet" zurückgegeben wird?
[Ist es explosiv?] Setup für die Verwendung der GPU-Version von Tensorflow unter OSX
rsync Das Verhalten ändert sich abhängig vom Vorhandensein oder Fehlen des Schrägstrichs der Kopierquelle
Ich habe versucht, es einfach zu machen, die Einstellung des authentifizierten Proxys auf Jupyter zu ändern