2016-06-20 4 views
1

Есть ли способ сделать нечеткое регулярное выражение в Julia?fuzzy regex matching in julia

Я построил следующее регулярное испытание выражения:

toMatch = Regex(word,"i") 
ismatch(toMatch,input_string) 

Я хотел бы быть в состоянии сделать это испытание, но допускают некоторую свободу в согласовании и указать это на расстояниях Левенштейн.

Я нашел пакет Levenshtein, который может рассчитать расстояние, но не уверен, как включить его в эту логику. Например:

levenshtein("hello","hllo")` 
> 1 
+0

Вам нужно regex здесь? Это звучит как сложная (вычислительная) проблема для общих регулярных выражений. –

+0

Возможно, мне это не нужно. Сначала я решил эту проблему для точных совпадений с использованием приведенного здесь кода, и теперь я пытаюсь разрешить принятие орфографических ошибок в ** input_string **. – Aaron

ответ

0

(Этот ответ не имеет ничего общего с регулярными выражениями, но он охватывает некоторые случаи использования.)

Я не знаю, если это работает для вашего использования. Но похоже, что вы пытаетесь найти, есть ли в вашем тексте слово (или близкое опечатку). Если текст разделены пробелами, и ваше слово не содержит пробелы, вы можете попробовать что-то вроде:

nopunct(s) = filter(c -> !ispunct(c), s) 
nfcl(s) = normalize_string(s, decompose=true, compat=true, casefold=true, 
           stripmark=true, stripignore=true) 
canonicalize(s) = nopunct(nfcl(s)) 
fuzzy(needle, haystack, n) = any(
    w -> levenshtein(w, canonicalize(needle)) < n, 
    split(canonicalize(haystack))) 

Что это, грубо:

nfcl нормализует строки с аналогичными «человеческими» появлений, путем снятия акцентов, игнорирования случая и выполнения нормализации юникода. Это очень полезно для нечеткого соответствия:

julia> nfcl("Ce texte est en français.") 
"ce texte est en francais." 

nopunct полосы знаки препинания, что еще больше упрощает строку.

julia> nopunct("Hello, World!") 
"Hello World" 

canonicalize просто объединяет эти два преобразования.

Затем мы проверяем, находится ли какое-либо из слов в стоге сена (разделенное пробелами) в пределах n иглы.

Примеры:

julia> fuzzy("Robert", "My name is robrt.", 2) 
true 

julia> fuzzy("Robert", "My name is john.", 2) 
false 

Это отнюдь не полное решение, но он охватывает много общих случаев использования. Для более продвинутых вариантов использования вы должны изучить более подробную информацию о the subject.

+0

Это очень полезно, однако в моем случае слово, которое я пытаюсь найти в моем тексте, может содержать пробелы в нем, поскольку это может быть фраза. Есть ли какие-либо изменения в этом, которые вы могли бы предложить, которые могли бы быть адаптированы? – Aaron

+0

@Aaron Если игла представляет собой обычную старую строку (никаких символов регулярных выражений, таких как '*' или '()'), есть «трюк», который вы могли бы сделать: вычислить 'levenshtein (needle, haystack)' и проверить, меньше длины (стога сена) - длина (игла) + n'. (Для того, чтобы получить от стога сена до иглы, нужно по крайней мере 'length (haystack) - длину (иглу)' символов, а затем, возможно, до 'n' дальнейших операций.) Это работает независимо от того, какие символы находятся в игле. –

+0

Я думаю, что это будет очень хорошо работать для моих нужд. Одна модификация, которую я добавлю, заключается в том, чтобы немного изменить 'n' как функцию« длины иглы ». – Aaron