对文本进行分词和标注
这里有一个简单的扫描器,它会根据一些规则把文本分成小块,并给这些小块打上标签。
- 处理未知字符的最好方法是什么?怎么把它们标记为未知?
- 有没有推荐的方法或库,可以在保持相对简单的同时,加快处理速度,达到类似的效果?
例子:
import re
def alpha(scanner,token):
return token, 'a'
def numeric(scanner,token):
return token,'rn'
def punctuation(scanner,token):
return token, 'p'
def superscript(scanner,token):
return token, 'sn'
scanner = re.Scanner([
(u"[a-zA-Z]+", alpha),
(u"[.,:;!?]", punctuation),
(u"[0-9]+", numeric),
(u"[\xb9\u2070\xb3\xb2\u2075\u2074\u2077\u2076\u2079\u2078]", superscript),
(r"[\s\n]+", None), # whitespace, newline
])
tokens, _ = scanner.scan("This is a little test? With 7,9 and 6.")
print tokens
输出:
[('This', 'a'), ('is', 'a'), ('a', 'a'), ('little', 'a'), ('test', 'a'),
('?', 'p'), ('With', 'a'), ('7', 'rn'), (',', 'p'), ('9', 'rn'),
('and', 'a'), ('6', 'rn'), ('.', 'p')]
注意! 定义的函数可能会进一步尝试对这些小块进行分类。
1 个回答
3
re.Scanner
是用来按照你提供的顺序匹配模式的。所以你可以在最后提供一个比较宽泛的模式来捕捉那些“未知”的字符:
(r".", unknown)
import re
def alpha(scanner,token):
return token, 'a'
def numeric(scanner,token):
return token,'rn'
def punctuation(scanner,token):
return token, 'p'
def superscript(scanner,token):
return token, 'sn'
def unknown(scanner,token):
return token, 'uk'
scanner = re.Scanner([
(r"[a-zA-Z]+", alpha),
(r"[.,:;!?]", punctuation),
(r"[0-9]+", numeric),
(r"[\xb9\u2070\xb3\xb2\u2075\u2074\u2077\u2076\u2079\u2078]", superscript),
(r"[\s\n]+", None), # whitespace, newline
(r".", unknown)
])
tokens, _ = scanner.scan("This is a little test? With 7,9 and 6. \xa0-\xaf")
print tokens
这样会得到
[('This', 'a'), ('is', 'a'), ('a', 'a'), ('little', 'a'),
('test', 'a'), ('?', 'p'), ('With', 'a'), ('7', 'rn'), (',', 'p'),
('9', 'rn'), ('and', 'a'), ('6', 'rn'), ('.', 'p'), ('\xa0', 'uk'),
('-', 'uk'), ('\xaf', 'uk')]
你的一些模式是 unicode
类型的,而有一个是 str
类型的。确实,在 Python2 中,模式和要匹配的字符串可以是 unicode
或 str
。
但是,在 Python3 中:
Unicode 字符串和 8 位字符串是不能混用的:也就是说,你不能用字节模式去匹配 Unicode 字符串,反之亦然。
因此,即使在 Python2 中,也最好不要混用这两种类型。
我觉得你的代码非常简单明了(除了 superscript
的正则表达式,真让人头疼!)。我不知道有没有哪个库能让它变得更简单。