搜索模式,同时排除输入中的某些字符

时间:2018-10-26 17:43:30

标签: javascript regex

这是我要解决的更大问题的一部分。我会同时提及它们。

说,用像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,则解决方案将失败。

我有另一种解决方案,但是很复杂。因此,我想知道,如果不使用库,什么是解决我的问题的最佳方法。

1 个答案:

答案 0 :(得分:2)

一个选择是,在针的每个字符之间使用[(insertedChars)]*来匹配可能插入的字符。对于您的特定示例,插入到两个字符之间的唯一字符是@,因此要查找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特殊字符,则它们必须为escaped first

对于动态针,您必须以编程方式在每个字符之间插入字符集。再次使用上面的示例:

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, '*$&@');