对文本进行分词和标注

1 投票
1 回答
1225 浏览
提问于 2025-04-17 13:13

这里有一个简单的扫描器,它会根据一些规则把文本分成小块,并给这些小块打上标签。

  1. 处理未知字符的最好方法是什么?怎么把它们标记为未知?
  2. 有没有推荐的方法或库,可以在保持相对简单的同时,加快处理速度,达到类似的效果?

例子:

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 中,模式和要匹配的字符串可以是 unicodestr

但是,在 Python3 中

Unicode 字符串和 8 位字符串是不能混用的:也就是说,你不能用字节模式去匹配 Unicode 字符串,反之亦然。

因此,即使在 Python2 中,也最好不要混用这两种类型。


我觉得你的代码非常简单明了(除了 superscript 的正则表达式,真让人头疼!)。我不知道有没有哪个库能让它变得更简单。

撰写回答