Поиск шаблона, исключая некоторые символы во входных данных

1

Это часть большей проблемы, которую я пытаюсь решить. Я расскажу им обоим.

Скажем, с иглой, подобной 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.

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

  • 0
    Извините, я до сих пор не понимаю, зачем вам форматировать строку?
  • 0
    @XTOTHEL Мне нужно отформатировать строку, чтобы я мог применить немного HTML для выделения. Например: если у меня есть отформатированная строка, такая как * Bir @ d, я могу заменить все * на <span class = 'highlight'> и @ на </ span>
Теги:

1 ответ

2
Лучший ответ

Один из вариантов - между каждым символом в игле использовать [ (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, '*$&@');
  • 0
    Большое спасибо за хорошо продуманный и тщательный ответ. Только что проверил с некоторыми входными данными, и это именно то, что я хочу. Я думаю, что я могу взять это отсюда и уточнить, как я считаю нужным.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню