Каков наиболее эффективный способ фильтрации массива сложных html строк на основе слов в JavaScript? - PullRequest
0 голосов
/ 18 июня 2020

На веб-странице stati c offline HTML у меня есть список сложных HTML строк, хранящихся в массиве JavaScript. Каждая строка может go до 28k символов, а может до 10k строк. Это выглядит так:

[
  "[...]rem;\">Jun 3, 2020 5:34 AM</span></div><div>Here are the requirements for t[...]",
  "[...]rem;\"></div><div>The design <span style=\"color:red\">proposals are actual[...]",
  "[...]un 3, 2020 5:35 AM</span></div><div></div>\n\n<pre>var response = Request.C[...]"
  // ... many more
]

На самом деле это сообщения, хранящиеся в HTML. Я должен найти способ отфильтровать их, поэтому, например, если я ищу те, которые содержат слова « дизайн » и « предложения », я получаю второе сообщение из списка выше в результате. Искомые слова могут быть в любой позиции в строке HTML, например, words.every(w => htmlString.indexOf(w) >= 0). Обратите внимание, что я не могу использовать этот код, потому что все теги HTML будут включены в поиск indexOf, и это может привести к ложным срабатываниям.

Поскольку код JavaScript выполняется в браузере, у меня есть доступ к DOM. Отфильтрованные сообщения будут отображаться после фильтрации с использованием разбивки на страницы.

Моя первая идея заключалась в l oop через все строки и:

  1. преобразовать их в HTML элементы с использованием document.createElement,
  2. Извлеките удобочитаемый текст с помощью innerText,
  3. Ищите слова в этом сглаженном тексте, поскольку теперь без тегов HTML это намного проще, используя indexOf.

Тестировал, работает хорошо. Но меня беспокоит производительность этого алгоритма, особенно с огромным количеством сообщений.

Видите ли вы какой-либо другой способ отфильтровать сообщение без необходимости конвертировать все сообщения в элементы DOM?

1 Ответ

0 голосов
/ 18 июня 2020

Использует Regex, который помещает нужные строки в группу захвата. Если группа захвата когда-либо совпадает, верните true. Исключает содержимое <style> и <script> и теги <>, сначала сопоставляя их.

console.log(
[
  "[...]rem;\">Jun 3, 2020 5:34 AM</span></div><div style='color:red'>Here are the requirements for t[...]",
  "[...]rem;\"></div><div>The design <span style=\"color:red\">proposals are actual[...]",
  "[...]un 3, 2020 5:35 AM</span></div><div>red</div>\n\n<pre>var response = Request.C[...]"
  // ... many more
].filter(str=>{
  const re = /<style[^>]+>.*?<\/style>|<script>.*?<\/script>|<[^>]+>|(red|design|proposals)/g
  let m
  while (m = re.exec(str))
    if(m[1]) return true
  return false
})
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...