2

我一直在努力用 Python 进行解码和编码,但我不太清楚如何解决我的问题。我正在遍历显然用 utf-8 编码的 xml 文本文件(示例),使用 Beautiful Soup 解析每个文件,然后查看文件中的任何句子是否包含来自两个不同单词列表的一个或多个单词。因为 xml 文件来自 18 世纪,所以我需要保留 xml 中的破折号。下面的代码很好地做到了这一点,但它也保留了我希望删除的讨厌的框字符。我相信盒子字符就是这个字符

(您可以在上面示例文件的第 3682 行中找到我希望删除的字符的示例。在此网页上,该字符看起来像一个“或”管道,但是当我在 Komodo 中读取 xml 文件时,它看起来像一个框。当我尝试将框复制并粘贴到搜索引擎中时,它看起来像一个“或”管道。但是,当我打印到控制台时,该字符看起来像一个空框。)

总而言之,下面的代码运行没有错误,但它打印出我想删除的空框字符。

for work in glob.glob(pathtofiles):

    openfile = open(work)
    readfile = openfile.read()
    stringfile = str(readfile)

    decodefile = stringfile.decode('utf-8', 'strict') #is this the dodgy line?
    soup = BeautifulSoup(decodefile)

    textwithtags = soup.findAll('text')

    textwithtagsasstring = str(textwithtags)

    #this method strips everything between anglebrackets as it should
    textwithouttags = stripTags(textwithtagsasstring)

    #clean text
    nonewlines = textwithouttags.replace("\n", " ")
    noextrawhitespace = re.sub(' +',' ', nonewlines)

    print noextrawhitespace #the boxes appear

我试图通过使用删除框

noboxes = noextrawhitespace.replace(u"\u2610", "")

但是 Python 抛出了一个错误标志:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 280: ordinal not in range(128)

有谁知道如何从 xml 文件中删除这些框?对于其他人可以提供的任何帮助,我将不胜感激。

4

3 回答 3

4

试试这个:

noextrawhitespace.replace("\\u2610", "") 

我认为您只是缺少那个额外的 '\'

这也可能有效。

print(noextrawhitespace.decode('unicode_escape').encode('ascii','ignore'))
于 2013-10-22T21:42:59.317 回答
4

问题是你正在混合unicodestr. 每当你这样做时,Python 必须将一个转换为另一个,这是通过 using 完成的sys.getdefaultencoding(),通常是 ASCII,这几乎不是你想要的。*

如果异常来自此行:

noboxes = noextrawhitespace.replace(u"\u2610", "")

...修复很简单...除了您必须知道noextrawhitespace应该是unicode对象还是 UTF-8 编码str对象)。如果是前者,那就是:

noboxes = noextrawhitespace.replace(u"\u2610", u"")

如果是后者,那就是:

noboxes = noextrawhitespace.replace(u"\u2610".encode('utf-8'), "")

但实际上,您必须使代码中的所有字符串保持一致;将两者混合起来会在比这更多的地方引起问题。


由于我没有要测试的 XML 文件,因此我编写了自己的:

<xml>
    <text>abc&#9744;def</text>
</xml>

然后,我将这两行添加到代码的底部(并在顶部添加了一点,只是打开我的文件而不是进行任何通配):

noboxes = noextrawhitespace.replace(u"\u2610".encode('utf-8'), "")
print noboxes

现在的输出是:

[<text>abc☐def</text>]
[<text>abc☐def</text>]
[<text>abcdef</text>]

所以,我认为这就是你想要的。


* 当然有时你想要 ASCII……但通常不是你有unicode对象的时候……</p>

于 2013-10-22T21:56:09.233 回答
1

阅读您的示例,以下是文档中的非 ASCII 字符:

0x2223 DIVIDES
0x2022 BULLET
0x3009 RIGHT ANGLE BRACKET
0x25aa BLACK SMALL SQUARE
0x25ca LOZENGE
0x3008 LEFT ANGLE BRACKET
0x2014 EM DASH
0x2026 HORIZONTAL ELLIPSIS

\u2223是第 3682 行中的实际字符,它被用作软连字符。其他用于标记难以辨认的字符,例如:

<GAP DESC="illegible" RESP="oxf" EXTENT="4+ letters" DISP="\u2022\u2022\u2022\u2022\u2026"/>

这是一些代码来执行您的代码正在尝试的操作。确保以 Unicode 处理:

from bs4 import BeautifulSoup
import re

with open('k000039.000.xml') as f:
    soup = BeautifulSoup(f)  # BS figures out the encoding

text = u''.join(soup.strings)      # strings is a generator for just the text bits.
text = re.sub(ur'\s+',ur' ',text)  # Simplify all white space.
text = text.replace(u'\u2223',u'') # Get rid of the DIVIDES character.
print text

输出:

[[截断]] 也认为我自己是新郎。扣上。我怀疑基奇不会找到他这样的人。[旁白] 萨戈夫人。好吧,——可怜的凯基一定要表现得很好,或者她已经完全失去了帕迪的宠爱。我要为《财富》的这番怨恨吗?——不。我很高兴我被原谅了。一些邻居的妻子最近才出现,当配偶离开他们时,他们所有的朋友都飞走了。那么你们所有的妻子会避免我的命运。对您目前的状态 FINIS 保持满意。

于 2013-10-23T02:56:19.737 回答