Python:从字符串中删除特定字符(u“\ u2610”)

时间:2013-10-22 21:37:48

标签: python xml string unicode ascii

我一直在用Python解码和编码,我无法弄清楚如何解决我的问题。我循环显示在utf-8中显然编码的xml文本文件(sample),使用Beautiful Soup来解析每个文件,然后查看文件中的任何句子是否包含来自两个不同列表的一个或多个单词的话。因为xml文件来自十八世纪,我需要保留xml中的em破折号。下面的代码做得很好,但它也保留了我想删除的讨厌的盒子字符。我相信盒子字符是this character

(您可以在上面的示例文件的第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文件中删除这些框?我会很感激别人可以提供的任何帮助。

3 个答案:

答案 0 :(得分:3)

尝试一下:

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

我认为你错过了额外的' \'

这也可能有用。

print(noextrawhitespace.decode('unicode_escape').encode('ascii','ignore'))

答案 1 :(得分:3)

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

如果异常来自这一行:

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

...修复很简单...除了你必须知道noextrawhitespace是{1}}对象还是UTF-8编码unicode对象之外。如果是前者,就是这样:

str

如果是后者,就是这样:

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

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


由于我没有测试你的XML文件,我自己写了:

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

然后,我将这两行添加到代码的底部(稍微向上打开我的文件,而不是为了什么而使用globbing):

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

输出现在是:

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

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


*当然有时你想要ASCII ......但是那些通常不是你拥有[<text>abc☐def</text>] [<text>abc☐def</text>] [<text>abcdef</text>] 个对象的时候......

答案 2 :(得分: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

输出:

  

[[truncated]]也认为我自己也是新郎。扣。我怀疑Kickey不会发现他这样。 [旁边。]萨戈太太。好吧,-poor Keckky受到良好行为的约束,或者她已经失去了她的Puddy's Favor。请问我在“财富”杂志的这篇报道? - 不。我很高兴Heart,我原谅了。一些邻居的妻子已经太晚了,当配偶离开时他们所有的朋友都飞了。然后你所有的妻子都会避免我的命运。对你目前的国家FINIS保持满意。