Найти совпадения запроса в строке - PullRequest
1 голос
/ 03 июля 2019

У меня есть задача вычислить символы для выделения в тексте на основе запроса. Допустим, данный текст "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. Итак, как я могу изменить свой код и решить проблему?

1 Ответ

1 голос
/ 04 июля 2019

Прежде всего, граница слова, которую вы добавляете, если первый символ представляет собой слово char, вероятно, должна быть согласована с несимвольными символами: если вы добавляете \b перед символьными символами, добавьте \B перед несловесными.Символы, чтобы получить то же поведение.

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]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...