【问题标题】:Can I use different codepoints in Python3?我可以在 Python3 中使用不同的代码点吗?
【发布时间】:2018-06-01 10:35:43
【问题描述】:

我遇到了很多从 C# 到 python 的字符串索引问题。基本上,现有的数据管道(在 C# 中)会生成一些字符串索引供 Python 模型使用。发生的事情是这两种语言在各自的 unicode 系统中使用不同的代码点,总结如下:http://illegalargumentexception.blogspot.com/2010/04/i18n-comparing-character-encoding-in-c.html

因此,C#(16 位,隐式 utf-16)中的字符串长度和索引在 Python(16 或 32)中不是 100% 相关的。有时,如果字符超过 0xFFFF(超过 16 位),Python 会生成比 C# 更小的字符串长度。

问题是:有没有办法确保字符串索引和长度相同?是否可以强制 Python 使用 C# 中的隐式 16 位?

一个具体的例子是这样的:

????????????, Ṣur

及其 utf-8 字节:

b'\xf0\x90\xa4\x91\xf0\x90\xa4\x85\xf0\x90\xa4\x93, \xe1\xb9\xa2ur'

在 Python 中,此字符串的长度为 12,而 C# 报告为 15。索引也将从一种语言变为另一种语言。

【问题讨论】:

  • 这不是 Python 中的字符串:它是原始字节序列。
  • 是一个字符串“????????????, Ṣur”,编码为u​​tf-8。由于复制和粘贴字符可能无法重现。我复制并粘贴字节以供调查。
  • 如果你调用.decode('utf-8'),那么你会得到一个字符串。但是您显示的不是字符串。
  • @JonathonReinhart 我用原文更新问题以进行澄清。无论如何,python 和 c# 报告不同的长度并为字符串使用不同的索引。
  • 您可能想看看在 C# 中使用 StringInfo 类。此类旨在允许检查字符串的单个字素,而不是可以分组为单个视觉“字符”的单个 UTF-16 代码点。我不确定 Python 中是否有类似的东西。

标签: c# python python-3.x unicode


【解决方案1】:

您可能希望在此处根据此答案使用StringInfo 类:Why is the length of this string longer than the number of characters in it?

using System;
using System.Text;
using System.Globalization;

namespace StackOverflow {
    class Program {
        public static void Main(string[] args) {
            var s = "???, Ṣur";
            // Len == 11
            Console.WriteLine("{0}: {1}", s, s.Length);

            // len == 8
            var si = new StringInfo(s);
            Console.WriteLine("{0}: {1}", s, si.LengthInTextElements);
        }
    }
}

或者,在 Python 端,您可以试试这个,但它与 C# 的长度并不完全相同,因为它假定为 2 字节,因此它仅涵盖前 65,536 个 UTF-16 字符:

#!/usr/bin/env python3

s = "???, Ṣur"
# len == 8 (displayable len)
print("{}: {}".format(s, len(s)))

# len == 11 (C# wackiness)
print(int(len(s.encode("utf-16")) / 2) - 1)

【讨论】:

  • 谢谢!这解决了从 C# 到 Python 的方向。你对从 Python 到 C# 的另一个方向有什么建议吗?
  • 只是出于好奇:当您组合变音符号时,StringInfo 会将它们视为单独的字符吗?如果不是,这将再次与 Python 计算字符的方式不同......
  • @YoHsiao - 我为 Python 添加了一个半等效的 UTF-16 长度示例。
猜你喜欢
  • 2014-11-05
  • 2019-01-22
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
  • 2021-01-29
  • 1970-01-01
  • 2013-09-16
相关资源
最近更新 更多