【发布时间】:2021-05-15 16:01:54
【问题描述】:
我有一堆需要处理的推文/线程数据集,以及一些单独的注释文件。这些注释文件由一些跨度组成,这些跨度由对应于单词/句子的索引表示。正如您可能已经预测的那样,索引是推文/线程文件中字符的位置。
当我处理带有一些表情符号的文件时,问题就出现了。举一个具体的例子:
这是相关文件的一部分 (download):
TeamKhabib ???????????? @danawhite @seanshelby @arielhelwani @AliAbdelaziz00 #McTapper xxxxx://x.xx/xxxxxxxxxx
mmafan1709 @TeamKhabib @danawhite @seanshelby @arielhelwani @AliAbdelaziz00 Conor is Khabib hardest fight and Khabib is Conors hardest fight
我在 python 中使用普通打开函数读取文件,参数 encoding='utf8':
with open('028_948124816611139589.branch318.txt.username_text_tabseparated', 'r', encoding='utf-8') as f:
content = f.read()
print(content[211:214])
注释说在 211-214 范围内有单词 and。我上面提到的阅读方式,有'kh'。
当我使用注释文件中的索引来获取跨越的字符串时,我得到的字符串是 3 个字符(右侧)。因为,在注释中,????显然需要 2 个空格。但是,当 python 读取它们时,它是一个,因此字符移位。当我用len(list(file.read())) 获得文件的长度时,它变得更加明显。这将返回 7809,而文件的实际长度是 7812。7812 是我在 vscode 中的文件末尾得到的位置,一个名为 vscode-position 的插件。另一个文件给我的 513 和 527 不一致。
阅读表情符号没有问题,我在输出/数组中看到它们,但是它们在编码中占用的空间不同。我的问题在其他相关问题中没有得到解答。
很明显,阅读这个文件是有道理的,因为这些文件是用某种格式/方法/概念/编码/无论这个插件和注释者同意的,但 open.read 不同意的。
我正在使用 python 3.8。
我在这里错过了什么?
【问题讨论】:
-
文本保存为 Unicode 代码点到字节的编码。 ???是单个代码点,但在 UTF-8 编码中编码为 3 个字节。 Python中Unicode字符串的长度是codepoints,文件的长度是bytes,所以会有区别。如果您的注释文件是字节索引,您可能需要将文件读取为二进制文件 (
'rb'),然后手动解码。 -
@MarkTolonen 嗯。正如您所说,我认为 7812 是字节偏移量,而 7809 是代码点。但是用 'rb' 读取它们然后应用 decode('utf8') 并没有任何区别。
-
不,读取二进制文件,获取特定偏移量的字节,然后解码。如果您需要解决方案,请发布带有适当注释和代码的真实示例文本,以显示您的问题。
-
@MarkTolonen 也没有用。假设它是字节偏移量,我错了,实际上文件是 7856 字节。通过这样做,我在左边得到了 6 个字符。并将文件添加到问题中。
-
如果没有附带的注释,它就真的没用了。我将发布一个我正在谈论的示例作为答案。
标签: python encoding utf-8 emoji