Я хочу использовать regexps для построения классификатора текстовых предложений (для обработки естественного языка чатбота).
У меня очень большое число (например, >> 100 ) различных типов текстовых предложений для соответствия шаблонам регулярных выражений.
Когда предложение соответствует регулярному выражению (скажем, намерение ), активирует определенное действие (обработчик функции).
Я предварительно настроил конкретноерегулярные выражения, чтобы соответствовать любому другому набору предложений, например:
// I have a long list of regexps (also many regexp for a many intents)
const regexps = [
/from (?<fromCity>.+)/, // ---> actionOne()
/to (?<toCity>.+)/, // ---> actionTwo()
/.../, // ---> anotherAction()
/.../ // ---> yetAnotherAction()
]
// I have a long list of actions (function handlers)
const actions = [
actionOne(),
actionTwo(),
...,
...
]
Как я могу построить самый быстрый (multi-regexp) классификатор (в Javascript)?
Мое текущее быстрое и грязное решение состоит в том, чтобы просто проверять каждое регулярное выражение последовательно:
// at run time
...
sentence = 'from Genova'
...
if (sentence.match(/from (?<fromCity>.+)/)
actionOne()
else if(sentence.match(/to (?<toCity>.+)/)
actionTwo()
else if ...
else if ...
else
fallback()
Приведенный выше последовательность if-then не очень масштабируема и, прежде всего, медленна с точки зрения производительности(даже если может помочь наиболее часто используемая сортировка регулярных выражений).
Альтернативный подход для улучшения производительности может быть следующим: создать одиночное (большое) регулярное выражение, составленное из названной группы (по одному на каждое совпадение-регулярное выражение) чередование ?
Как в минимальном примере:
const regexp = /(?<one>from (?<toCity>.+))|(?<two>to (?<toCity>.+))/
Поэтому я создаю классификатор регулярных выражений просто с помощью (пожалуйста, используйте код ниже как псевдокод javascript):
// at build time
// I collect all possible regexps, each one as a named group
const intents = [
'(?<one>from (?<fromCity>.+))',
'(?<two>to (?<toCity>.+))',
'...',
'...'
]
const classifier = new RegExp(intents.join('|'))
// collection of functions handlers, one for each regexp
const Actions = {
'one': 'actionOne',
'two': 'actionTwo',
...,
...
}
// at run time
const match = sentence.match(classifier)
// if match, call corresponding function handler
// match.groups contains the matching named group
const action = Actions[match.groups]
if ( action )
action()
else
fallback() // no match
Имеет ли это смысл?Любое предложение для лучшего подхода?