nltk 正则表达式分词器

Posted

技术标签:

【中文标题】nltk 正则表达式分词器【英文标题】:nltk regular expression tokenizer 【发布时间】:2016-07-21 01:42:25 【问题描述】:

我尝试在python中用nltk实现一个正则表达式分词器,结果是这样的:

>>> import nltk
>>> text = 'That U.S.A. poster-print costs $12.40...'
>>> pattern = r'''(?x)    # set flag to allow verbose regexps
...     ([A-Z]\.)+        # abbreviations, e.g. U.S.A.
...   | \w+(-\w+)*        # words with optional internal hyphens
...   | \$?\d+(\.\d+)?%?  # currency and percentages, e.g. $12.40, 82%
...   | \.\.\.            # ellipsis
...   | [][.,;"'?():-_`]  # these are separate tokens; includes ], [
... '''
>>> nltk.regexp_tokenize(text, pattern)
[('', '', ''), ('', '', ''), ('', '-print', ''), ('', '', ''), ('', '', '')]

但想要的结果是这样的:

['That', 'U.S.A.', 'poster-print', 'costs', '$12.40', '...']

为什么?哪里错了?

【问题讨论】:

尝试from nltk.tokenize import RegexpTokenizertokenizer = RegexpTokenizer(pattern) 然后tokenizer.tokenize(text) 它在我的笔记本中返回['That', 'U.S.A.', 'poster-print', 'costs', '$12.40', '...']。可能是版本问题? (3.0.4) 我尝试使用 python 3.5 但结果是这样的: [('', '', ''), ('', '', ''), ('', '-print ', ''), ('', '', ''), ('', '', '')] 啊哈,您应该将所有捕获组设置为非捕获。 ([A-Z]\.)+ > (?:[A-Z]\.)+, \w+(-\w+)* -> \w+(?:-\w+)*\$?\d+(\.\d+)?%?\$?\d+(?:\.\d+)?%? 请看github.com/nltk/nltk/issues/1206#issuecomment-156470847 【参考方案1】:

您应该将所有捕获组变为非捕获组:

([A-Z]\.)+ > (?:[A-Z]\.)+ \w+(-\w+)* -> \w+(?:-\w+)* \$?\d+(\.\d+)?%?\$?\d+(?:\.\d+)?%?

问题是regexp_tokenize 似乎在使用re.findall,当模式中定义了多个捕获组时,它会返回捕获元组列表。见this nltk.tokenize package reference:

pattern (str) – 用于构建此分词器的模式。 (此模式不得包含捕获括号;请改用非捕获括号,例如 (?:...))

另外,我不确定您是否想使用匹配包含所有大写字母的范围的:-_,请将- 放在字符类的末尾。

因此,使用

pattern = r'''(?x)          # set flag to allow verbose regexps
        (?:[A-Z]\.)+        # abbreviations, e.g. U.S.A.
      | \w+(?:-\w+)*        # words with optional internal hyphens
      | \$?\d+(?:\.\d+)?%?  # currency and percentages, e.g. $12.40, 82%
      | \.\.\.              # ellipsis
      | [][.,;"'?():_`-]    # these are separate tokens; includes ], [
    '''

【讨论】:

以上是关于nltk 正则表达式分词器的主要内容,如果未能解决你的问题,请参考以下文章

NLTK 正则表达式标记器在正则表达式中不能很好地处理小数点

如何使用组名使用正则表达式实现高效的分词器

NLTK 正则表达式和 CFG

NLTK - nltk.tokenize.RegexpTokenizer - 正则表达式未按预期工作

无法在正则表达式和 nltk 的帮助下删除特殊字符

如何使用 nltk 正则表达式模式来提取特定的短语块?