如何使用复杂的 token_match 自定义分词器?

How to customize tokenizer with complex token_match?

我正在使用 spacy 来做一些定制的分词器。我想将 API 名称作为一个 token。如srcs[offset].remaining()句中:

Up to the first srcs[offset].remaining() bytes of this sequence are written from buffer srcs[offset].

我已将 token_match 添加到 tokenizer,但它已被后缀覆盖。

代码如下:

import re
import spacy
from spacy.tokenizer import Tokenizer

def customize_tokenizer_api_name_recognition(nlp):
    # add api_name regex, such aaa.bbb(cccc) or aaa[bbb].ccc(ddd)
    api_name_match = re.compile("(\w+(\[[\w+-]+\])?\.)+\w+\(.*?\)", re.UNICODE).match
    nlp.tokenizer.token_match = api_name_match

if __name__ == '__main__':
    nlp = spacy.load('en_core_web_sm')
    customize_tokenizer_api_name_recognition(nlp)
    sentence = "Up to the first srcs[offset].remaining() bytes of this sequence are written from buffer srcs[offset]."
    doc = nlp(sentence)
    print([token.text for token in doc])
    # output:  ['Up', 'to', 'the', 'first', 'srcs[offset].remaining', '(', ')', 'bytes', 'of', 'this', 'sequence', 'are', 'written', 'from', 'buffer', 'srcs[offset', ']', '.']
    # expected output: ['Up', 'to', 'the', 'first', 'srcs[offset].remaining()', 'bytes', 'of', 'this', 'sequence', 'are', 'written', 'from', 'buffer', 'srcs[offset', ']', '.']

我看到了一些相关问题#4573, #4645 and the doc。然而所有的例子都是简单的正则表达式,他们通过删除一些 prefixes_search 来解决。复杂的正则表达式呢?如何解决这类问题?

ps:我以前是用doc.retokenize()来实现的。能否通过自定义tokenizer更优雅的解决问题?

环境

tokenizer 解决方案与#4573 相同,只是您自定义了后缀。不过,这不是一个很好的解决方案,因为 ) 在任何地方都不是后缀。

我认为 doc.retokenize() 的解决方案更适合 v2.2。您可以在添加到管道开头的小型自定义管道组件中执行此操作。

(有两个 token_match 选项可能更好,一个有前缀和后缀,一个没有,但让分词器选项比现在更复杂也不是很好。)