gpt4 book ai didi

java - python 中的 utf-8 字符串索引与 java 不兼容

转载 作者:行者123 更新时间:2023-12-01 22:25:30 24 4
gpt4 key购买 nike

我有一个包含以下内容的文本文件:

 🔴🔴🔴🔴🔴\n==================\0No. 4♨ ==\n📌 \n✅IHappy Holi\n✅Ground Floor or Second Floor\n9910080224\nemailaddress@gmail.com

我有一个在服务器中运行的Python代码来查找我想要与文本一起传递的索引,以便在客户端上突出显示。以下是相关代码:

import re
f = open('data.json', 'r')
text = f.readline().strip().decode('UTF-8').encode('UTF-8')
f.close()

for m in re.finditer(r'emailaddress', text, flags=re.IGNORECASE):
s = m.start()
e = m.end()
print s, e
print text[s:e]

输出为:

123 135
emailaddress

现在在客户端,我有java代码(在android上)。然而这些索引根本不起作用。

public class HelloWorld {
public static void main(String[] args) {
String text = "🔴🔴🔴🔴🔴\n==================\0No. 4♨ ==\n📌 \n✅IHappy Holi\n✅Ground Floor or Second Floor\n9910080224\nemailaddress@gmail.com";
System.out.println(text.substring(**115**));
}
}

输出是:

l.com

我确信我在字符串编码中犯了一些错误。有人可以帮我吗?

最佳答案

Python 端使用 UTF-8 编码数据(大小不同),Java 代码使用 UTF-16 codeunits *。其中一个的索引不会映射到另一个。

在 Python 2.7 UCS-2 构建(与 Java 一样使用 UTF-16 代理项对)中将索引应用到示例字符串(作为 Unicode 字符串并编码为 UTF-8)时,您会发现问题:

>>> u"🔴🔴🔴🔴🔴\n==================\0No. 4♨ ==\n📌 \n✅IHappy Holi\n✅Ground Floor or Second Floor\n9910080224\nemailaddress@gmail.com"[115:]
u'l.com'
>>> u"🔴🔴🔴🔴🔴\n==================\0No. 4♨ ==\n📌 \n✅IHappy Holi\n✅Ground Floor or Second Floor\n9910080224\nemailaddress@gmail.com".encode('utf8')[115:]
'\nemailaddress@gmail.com'

UTF-8 将 Unicode 代码点编码为每个代码点 1 和 4 个代码单元;使用多少个代码单元取决于文本:

>>> len(u'abc'.encode('utf8'))
3
>>> len(u'åßç'.encode('utf8'))
6

在将 Unicode 解码为内部 UTF-16 表示形式时(就像 Java 所做的那样,以及具有默认窄 UCS-2 构建的 Python 2.7),大多数字符仅使用一个代码单元,而 BMP 之外的字符(例如表情符号)则使用2:

>>> u"🔴📌✅"
u'\U0001f534\U0001f4cc\u2705'
>>> len(u"🔴📌✅")
5
>>> u"🔴📌✅".encode('utf8')
'\xf0\x9f\x94\xb4\xf0\x9f\x93\x8c\xe2\x9c\x85'
>>> len(u"🔴📌✅".encode('utf8'))
11

在 Python 中对 Unicode 值运行正则表达式(例如从 UTF-8 解码),或者更改 Java 代码以对 UTF-8 字节而不是 UTF-16 代码单元进行操作。

如果您在 Python 中使用 Unicode,请考虑到您还可以使用 UCS-4 作为 Unicode 代码点构建 Python 二进制文件;你永远不会看到代理,并且 Python 中字符串的长度将与 Java 表示的长度不同。 Python 3.3 及更高版本使用 flexible storage其中内部表示永远不会使用代理,而是进行缩放以满足每个单独字符串的要求。

在这种情况下,您可能需要使用 JSR-204 methods访问 Java 端的代码点;我怀疑String.offsetByCodePoints()在这里会很有帮助,但我不是 Java 开发人员。

您可能想温习一下 Unicode 和编解码器;我建议您阅读:

<小时/>

* Java 的 String 类型使用 UTF-16 字,每个代码单元 2 个字节。对于 BMP 之外的字符,这意味着每个字符使用 surrogate pairs 两个代码单元。 .

关于java - python 中的 utf-8 字符串索引与 java 不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28858212/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com