4

我在 Bodo 语言中使用 python 2.7 进行 NLP(使用Devnagari脚本)

在去除停用词的过程中,我在一个文件中制作了一个停用词列表,由换行符(“\n”)分隔。我使用编解码器模块读取此文件并转换为列表。

raw_txt = codecs.open('stopwords.txt', 'r', 'utf-8')
stopWords = []
while(1):
    line = raw_txt.readline()
    if not line:
        break
    line = u''.join(line.strip())
    stopWords.append(line)

现在我编译了一个正则表达式来查找匹配的单词:

def addWordBoundary(word):       
    return u''.join(r"\b" + word + r"\b")

reg = regex.compile(r"(%s)" % "|".join(map(addWordBoundary, stopWords)), regex.UNICODE)

我使用编解码器模块将语料库(文本文件)读取到字符串和 regex.sub(),然后使用编解码器本身将其写入文件。但它漏掉了一些词。我不知道为什么。

fl = codecs.open('corpus.txt', 'r', 'utf-8')
rawFile = fl.read()

cleanText = reg.sub('', rawFile, regex.U)

wr = codecs.open('output.txt', 'w', 'utf-8')
wr.write(cleanText)
wr.close()

出于测试目的,将其用作 stopwords.txt 和 corpus.txt

<br>
<br> <br> <br> <br> <br>
<br>
<br>
<br>
<br>

output.txt 文件必须是一个空文件,但它包含:

रावनिफ्रायबो<br> इफोरनिफ्राय

此代码适用于英文文本(ASCII),所以可能是我在处理 utf-8 时做错了什么。请建议。

4

1 回答 1

2

您提供的文件中的某些停用词以未定义为字母数字的字符开头或结尾:

import unicodedata as ud
for w in stopWords:
    for c in w[0], w[-1]:
        print repr(c), ud.category(c),
    print
u'\u092e' Lo u'\u094b' Mc
u'\u092b' Lo u'\u094b' Mc
u'\ufeff' Cf u'\u094b' Mc
u'\u092e' Lo u'\u092f' Lo
u'\u091c' Lo u'\u092f' Lo
u'\u0905' Lo u'\u092f' Lo
u'\ufeff' Cf u'\u092f' Lo
u'\u0928' Lo u'\u094b' Mc
u'\u092b' Lo u'\u092f' Lo
u'\u0928' Lo u'\u094b' Mc

特别是,两行 - 您在 output.txt 中看到的 - 以 开头u'\ufeff'

ud.name(u'\ufeff') == 'ZERO WIDTH NO-BREAK SPACE'

这也称为字节顺序标记 (BOM),有时用于文件开头以识别编码。在这里,它可能在编辑时意外包含在文件中。如果该字符位于文件的最开头,Python 似乎确实会删除该字符,但当它出现在文件的其他位置时则不会。strip()显然也不足以删除它。应手动从输入文件中删除这些字符。

我还在输出中得到了以u'\u094b'( DEVANAGARI VOWEL SIGN O ) 结尾的那些,所以我的 Python 副本显然没有将这些视为字母数字字符。

此外,一般来说,当您想要匹配正则表达式中的精确字符串时,您应该re.escape(string)在将其插入正则表达式之前使用,以防字符串包含将被视为正则表达式元字符的字符。

于 2013-06-02T20:13:43.400 回答