在Python中去除'\xad'的最佳方法是什么?

14
我正在尝试从此链接中找到的.txt文件中构建语料库。我认为\xad的实例应该是所谓的“软连字符”,但在UTF-8编码下似乎无法正确读取。我已尝试将.txt文件编码为iso8859-15,使用以下代码:
with open('Harry Potter 3 - The Prisoner Of Azkaban.txt', 'r', 
encoding='iso8859-15') as myfile:
data=myfile.read().replace('\n', '')

data2 = data.split(' ')

这将返回一个“单词”数组,但是'\xad'仍然附加在data2的许多条目中。我尝试过

data_clean = data.replace('\\xad', '')

and

data_clean = data.replace('\\xad|\\xad\\xad','')

但这似乎没有移除 '\xad' 的实例。有人遇到过类似的问题吗?理想情况下,我想将这些数据编码为 UTF-8,以便使用 nltk 库,但是当我使用 UTF-8 编码读取文件时,会出现以下错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xad in position 471: invalid start byte

任何帮助都将不胜感激!
额外的背景信息:这是一个娱乐项目,旨在能够根据txt文件生成故事。到目前为止,我生成的所有内容都被'\xad'所影响,这破坏了乐趣!

1
你的字符串中没有字符序列反斜杠-x-a-d;你实际上有软连字符。如果在打印输出中看到反斜杠-x-a-d,那么你可能做错了一些事情,比如打印字符串列表而不是打印字符串,或者使用字符串的 repr - user2357112
它们应该是普通连字符而不是软连字符,但这是另一个问题。 - user2357112
那么,为什么你尝试将文件编码为iso8859-15呢?你需要iso8859-15字节吗?如果是这样,为什么要尝试以UTF-8格式读取它们呢? - abarnert
1
@user2357112 实际上,使用常规连字符可能会很烦人,除非你想在小说中几乎一半的单词中插入连字符。最好什么都不要,如果有人想把它渲染成书,就信任他们的连字词典。 - abarnert
@abarnert:不,该文件中软连字符的位置应该是需要普通连字符的地方,比如“eagle-feather quill”和“jet-black hair”。我在文件中找到的所有软连字符都不是在音节断点处。 - user2357112
1个回答

22

你的文件中几乎肯定包含了实际的U+00AD软连字符

这些字符标记了在将行适应页面时单词可能被分割的位置。这样做的想法是,如果单词不需要被分割,软连字符是看不见的,但如果需要分割,则与U+2010普通连字符相同。

既然您不关心在流畅的文本书中呈现此文本,您永远不会对任何内容进行连字处理,因此您只需删除这些字符即可。

要做到这一点,不要调整编码。只需从Unicode文本中删除它们,使用以下其中之一,以便您找到最易读的那个:

data = data.replace('\xad', '')
data = data.replace('\u00ad', '')
data = data.replace('\N{SOFT HYPHEN}', '')

请注意单个反斜杠。我们不是替换一个字面上的反斜杠,xad,我们正在替换一个字面上的软连字符,也就是其代码点为十六进制0xad的字符。
您可以在拆分成单词之前对整个文件执行此操作,也可以在拆分后每个单词执行一次。

同时,您似乎对编码方式以及如何处理它们感到困惑:

我尝试将.txt文件编码为iso8859-15

不,您尝试的是将文件解码为ISO-8859-15。不清楚您为什么首先选择了ISO-8859-15。但是,由于字符'\xad'的ISO-8859-15编码是字节b'\xad',也许是正确的。

理想情况下,我希望将这些数据编码为UTF-8以使用nltk库

但是NLTK不需要UTF-8字节,它需要Unicode字符串。您不需要为此进行编码。

此外,您并不是在尝试将Unicode文本编码为UTF-8,而是在尝试从UTF-8解码字节。如果那些字节不是UTF-8的,如果幸运的话,您会得到像这样的错误;如果不幸的话,您将得到您没有注意到的乱码,直到您搞砸了500GB的语料库并且抛弃了原始数据。1


1. UTF-8被专门设计为尽可能早地发现错误。在这种情况下,将ISO-8859-15文本读取为UTF-8时,如果其中包含软连字符,则会引发与您看到的完全相同的错误,但是将带有软连字符的UTF-8文本读取为ISO-8859-15将会悄无声息地成功,但每个软连字符之前都会多出一个'Â'字符。错误通常更有帮助。


谢谢。我尝试了替代的 UTF-8 解码方式,因为它们似乎效果更好(与我尝试使用 UTF-8 解码时没有显示相同的错误)。我认为 UTF-8 只是 nltk 函数的默认解码方式,所以我确实混淆了编码和解码这两个概念。 - Data Science Officer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接