簡體   English   中英

Python3 計算字符串中的 UTF-16 代碼點

[英]Python3 counting UTF-16 code points in a string

我試圖弄清楚如何將UTF-16偏移量轉換為UTF-8偏移量,或者以某種方式能夠計算字符串中UTF-16代碼點的數量。 (我認為為了做前者,無論如何你必須做后者。)

完整性檢查:我是正確的, len() function 在 python 字符串上操作時返回UTF-8中的代碼點數?

我需要這樣做,因為LSP 協議要求偏移量為UTF-16 ,並且我正在嘗試構建一些考慮到 LSP 的東西。

我似乎找不到如何做到這一點,我所知道的唯一python LSP 服務器本身甚至不處理這種轉換。

Python 有兩種可用於字符的數據類型,這兩種數據類型都不代表 UTF-16 代碼單元。

在 Python-3 中,字符串表示為str對象,它們在概念上是 unicode 代碼點的向量。 所以str的長度是它包含的 Unicode 字符的數量,並且len("")是 1,就像任何其他單個字符一樣。 這與""需要兩個 UTF-16 代碼單元(或四個 UTF-8 代碼單元)這一事實無關。

Python-3 還有一個bytes object,它是一個字節向量(顧名思義)。 您可以使用encode方法將str編碼為字節序列,並指定一些編碼。 因此,如果您想生成代表 UTF-16LE 中字符 "" 的字節 stream,您將調用"".encode('utf-16-le')

指定le (對於 little-endian)很重要,因為encode會生成 stream 字節,而不是 UTF-16 代碼單元,並且每個代碼單元需要兩個字節,因為它是一個 16 位數字。 如果您不指定字節順序,如在encode('utf-16')中,您會在編碼的 stream 的開頭找到一個兩字節的 UFtF-16 字節順序標記。

由於 UTF-16 編碼每個 UTF-16 代碼單元需要兩個字節,因此您可以通過將編碼字節 object 的長度除以 2 來獲得 unicode 字符串的 UTF-16 長度: s.encode('utf-16-le')//2 .

但這是在 UTF-16 偏移量和字符索引之間進行轉換的一種非常笨拙的方式。 相反,您可以使用這樣一個事實,即可以用單個 UTF-16 代碼單元表示的字符正是代碼點小於 65536 (2 16 ) 的字符:

def utf16len(c):
    """Returns the length of the single character 'c'
       in UTF-16 code units."""
    return 1 if ord(c) < 65536 else 2

為了計算字節數,包括 BOM, len(str.encode("utf-16"))會起作用。 您可以將utf-16-le用於沒有 BOM 的字節。

例子:

>>> len("abcd".encode("utf-16"))
10
>>> len("abcd".encode("utf-16-le"))
8

至於你的問題:不,Python 中的len(str)檢查解碼字符的數量。 如果一個字符占用 4 個 UTF-8 代碼點,它仍然算作 1。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM