Это часть большей проблемы, которую я пытаюсь решить. Я расскажу им обоим.
Скажем, с иглой, подобной bi
и стоге сена, например Bird
, я мог бы использовать следующий код для поиска иглы и применить некоторое форматирование к стоге сена:
const regExp = new RegExp(/bi/, 'gi');
inputStr = inputStr.replace(regExp, '*' + '$&' + '@');
Вышеизложенное будет мутировать inputStr как: *Bi@rd
(я объясню позже, почему я форматирую.)
Теперь, можно найти этот модифицированный стог *Bi@rd
для иглы ir
?
Большая проблема, которую я пытаюсь решить: найти несколько игл в стоге сена и выделить их. Иглы появятся в виде разделенной пробелом строки. Столбец - это имена пользователей, поэтому не очень долго.
Это одно из решений, с которыми я столкнулся:
function highlighter(inputStr, searchQuery) {
const needles = searchQuery.split(' ');
let regExp;
needles.forEach((pattern) => {
regExp = new RegExp(pattern, 'gi');
inputStr = inputStr.replace(regExp, '*' + '$&' + '@');
});
const highlightedStr = inputStr.replace(/[*]/g, '<span class="h">').replace(/[@]/g, '</span>');
return highlightedStr;
}
Мое решение не удастся, если я попытаюсь выделить bi ir
в Bird
.
У меня другое решение, но это сложно. Так что интересно, если не использовать библиотеку, что лучший способ решить мою проблему.
Один из вариантов - между каждым символом в игле использовать [
(insertChars) ]*
для необязательного совпадения с символами, которые могут быть вставлены. Для вашего конкретного примера единственным символом, вставленным между символами, является @
, поэтому, чтобы найти ir
, вы должны использовать:
i[@]*r
Но в этом наборе символов есть только один символ, поэтому он сводится к i@*r
. Пример:
const haystack = '*Bi@rd';
const re = /i@*r/i;
console.log(haystack.replace(re, '<<foobar>>'));
Другой пример: если вставленные символы могут быть @
, #
или %
в стоге сена qw##e@%rty
с иглой wer
:
const haystack = 'qw##e@%rty';
const re = /w[@#%]*e[@#%]*r/i;
console.log(haystack.replace(re, '<<foobar>>'));
Также обратите внимание, что если элементы searchQuery
могут содержать специальные символы RE, они должны быть экранированы первыми.
Для динамической иглы вам придется вводить набор символов между каждым символом программно. Повторное использование приведенного выше примера:
const escape = s => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
const haystack = 'qw##e@%rty';
const needle = 'wer';
const inserted = '@#%';
const re = new RegExp(
escape(needle).replace(/\\?.(?!^)/g, '$&[' + inserted + ']*'),
'gi'
);
console.log(haystack.replace(re, '<<foobar>>'));
Другое дело иметь в виду, что вместо того, чтобы объединять три строки вместе, вы можете просто использовать одну большую строку:
inputStr = inputStr.replace(regExp, '*$&@');