我有一个包含以下内容的文本文件:
\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
我确信我在编码字符串时犯了一些错误。有人可以帮我这个。
答案 0 :(得分:3)
Python端使用UTF-8编码数据(大小不等),Java代码使用UTF-16 codeunits * 。一个指数不会映射到另一个。
在Python 2.7 UCS-2版本(使用像Java那样使用UTF-16代理对)时,将索引应用于示例字符串(Unicode字符串并编码为UTF-8)时,您可以看到问题:< / p>
>>> 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所示,以及Python 2.7使用默认的窄UCS-2版本),大多数字符只使用一个代码单元,而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每个字符使用两个代码单元。