我正在尝试执行正则表达式来匹配文档中的多个 n-gram。我首先得到一个 n-gram 列表,我将它们编译成一个正则表达式,如下所示:
sNgrams = '|'.join(('\s+'.join(re.escape(gram) for gram in nGram.split())) for nGram in aNgrams)
(将 n-gram 拆分为任何空白字符上的标记,重新转义这些标记并使用 '\s+'-es 加入它们(这样我就可以通过换行符、双空格、制表符等匹配 ngram),然后加入正则表达式带有“|”的 n-gram)
我的正则表达式如下所示:
reNgram = re.compile('(\A|\W+)(' + sNgrams + ')(?=\W+|\Z)',flags=re.UNICODE|re.IGNORECASE)
现在,这在大多数情况下都可以正常工作,但是,当一个 n-gram 与另一个 n-gram 重叠时,只会找到一个匹配项:
doc = 'aap noot mies'
aNgrams = ['aap','noot','aap noot']
sNgrams = 'aap|noot|aap\\s+noot'
re.findall(reNgram,doc)
[('', 'aap'), (' ', 'noot')]
aNgrams = ['mies','aap noot']
re.findall(reNgram,doc)
[('', 'aap noot'), (' ', 'mies')]
有没有办法解决这个问题?返回文档中匹配的所有(子)字符串?
此外,速度/效率非常重要(我正在解雇数以万计的这些正则表达式),我可以做些什么来优化?我读过预编译正则表达式并没有多大作用,因为无论如何都会缓存“即时”编译的正则表达式,我可以采取任何(其他)明显的步骤来加速这些表达式吗?