在字符串中查找查询匹配项

Find query matches within a string

我的任务是根据查询计算要在文本中突出显示的字符。 假设给定的文本是 "London, United Kingdom",查询是 "lond"。那么结果应该是[[0, 4]].

我有一个简单的实现,适用于这种情况:

// ...
.reduce((result, word) => {
  const wordLen = word.length;
  const prefix = wordCharacterRegex.test(word[0]) ? "\b" : "";
  const regex = new RegExp(prefix + escapeRegexCharacters(word), "i");
  const index = text.search(regex);

  if (index > -1) {
    result.push([index, index + wordLen]);

    text =
      text.slice(0, index) +
      new Array(wordLen + 1).join(" ") +
      text.slice(index + wordLen);
  }

  return result;
}, [])
// ...

但是如果文本是 "EC2V 6DB, London, United Kingdom" 并且查询是 "ec2v6db" 它就不起作用,因为正则表达式将是 /\bec2v6db/i。 那么,我该如何更改我的代码并解决问题呢?

首先,如果第一个字符是字符字符,则添加的单词边界应该与 non-word 个字符一致:如果在字符字符之前添加 \b,请添加 \B 在 non-word 字符之前获得相同的行为。

const prefix = wordCharacterRegex.test(word[0]) ? "\b" : "\B";

然后,不清楚您的 escapeRegexCharacters 方法是什么样的,但您可以在关键字的每个字符之间插入 \s*

function escapeRegexCharacters(s) {
    var res = s.replace(/([-\/\^$*+?.()|[\]{}])|[\s\S]/g, (m,g) => (g ? "\" + g : m) + "\s*");
    return res.substring(0, res.length -3);
}

这是一个演示:

let word = "ec2v6db"; // lond is checked
let text = "EC2V 6DB, London, United Kingdom";
const wordCharacterRegex = /\w/;

function escapeRegexCharacters(s) {
    var res = s.replace(/([-\/\^$*+?.()|[\]{}])|[\s\S]/g, (m,g) => (g ? "\" + g : m) + "\s*");
    return res.substring(0, res.length -3);
}

const prefix = wordCharacterRegex.test(word[0]) ? "\b" : "\B";
const regex = new RegExp(prefix + escapeRegexCharacters(word), "i");

// Replacing text with spaces
console.log(text.replace(regex, m => " ".repeat(m.length)));
// => "        , London, United Kingdom"

// Adding tags around the match
console.log(text.replace(regex, "<highlight>$&</highlight>"));

// Getting the indices:
let match = regex.exec(text);
if (match) {
   console.log([match.index, match.index+match[0].length]);
}