2015-08-21 3 views
2

Я пытаюсь найти совпадения между словами и там уменьшенную форму, используя Elasticsearch.Fuzzy regex Elasticsearch

Пусть у меня есть входное слово shmp (индексируется shampoo в ES), я произвожу следующее регулярное выражение s.*?h.*?m.*?p.*? и выполнить следующий DSL запрос:

{ 
    "query": { 
    "regexp": { "name": "s.*?h.*?m.*?p.*?" } 
    } 
} 

Есть ли способ также сделать нечеткий поиск в то же время (например, max_expansions 1), чтобы s.*h.*?n.*?p.*? соответствовал бы?

Однако я не уверен, что это лучший способ пойти, возможно, есть некоторые работы, о которых я не думал.

+0

Как насчет 's. *? H. *? [Mn]. *? P. *?'? – Kasramvd

+0

Фактически письмо, которое может расходиться, неизвестно. Слишком легко в противном случае;) – Orelus

+0

Так что в этом случае вы можете использовать диапазон символов 's. *? H. *? [Az]. *? P. *?' Или другое регулярное выражение, например, вы также можете использовать '\ w' для соответствия всем символам слов. – Kasramvd

ответ

0

(..*?h.*?m.*?p.*?|s.*?..*?m.*?p.*?|s.*?h.*?..*?p.*?|s.*?h.*?m.*?..*?)

https://regex101.com/r/qV9cW6/1

Это своего рода запутанна, чтобы произвести вручную, потому что она будет включать в себя оператор ИЛИ с числом членов, равным числу букв в вводе. Но если бы вы использовали цикл, было бы неплохо создать его для произвольного ввода. Способ, которым он работает, заключается в том, что он допускает случаи, когда любой из четырех символов shmp отличается от другого, но не более одного.

+0

Является ли регулярное выражение единственным способом для нечеткой части поиска? (смотреть только с использованием регулярных выражений, а не встроенных функций ES).Позвольте сказать, что я хочу max_expansions из 4 на 8 буквенных словах, регулярное выражение будет довольно большим. – Orelus

+0

Может быть, лучший способ сделать это с помощью функций ES - я не знаком с Elasticsearch (только для регулярного выражения), поэтому я не уверен. – ezig

1

Это решение отличается от ответа @ ezig. Другой взгляд на него: р

^(.*?([^s](?=.*?h.*?m.*?p)|s).*?([^h](?=.*?m.*?p)|h).*?([^m](?=.*?p)|m).*?.) 

Regex101

Как это регулярное выражение в основном работает в том, что каждая буква получает секцию. Для этого объяснения мы будем использовать s, так как это первый.

S: ([^s](?=.*?h.*?m.*?p)|s)

Это говорит «вы позволили не совпадать с s здесь при условии, что остальная часть строки будет должным образом соответствовать в противном случае мы должны совпадать с s здесь»

Для посмотрите, почему это регулярное выражение будет расти медленнее, чем ответ @ ezig заключается в том, что мы знаем, что первый персонаж будет следовать правилам вашего нечеткого соответствия, и нам не нужно быть слишком умными с дополнительными символами.

H: ([^h](?=.*?m.*?p)|h)

Раздел замкнута, потому что мы знаем, что если s не совпадают, мы не соответствовать строке на всех, но так как мы проверка h здесь, и это может быть другим мы его знаем должен был соответствовать s ранее. Это говорит «Если остальная часть строки соответствует правильно, мы можем сопоставить что-то, отличное от h».