Проблема производительности при замене текста innerHTML с помощью регулярного выражения - PullRequest
1 голос
/ 04 июля 2019

Я сталкиваюсь с проблемой производительности при вызове метода, который заменяет текст innerHTML с помощью регулярного выражения:

function getReplacedText(textToReplace) {
  return textToReplace.replace(/\<img src=[\"|\']([\S\s]+\\)*([\S\s]+).png[\"|\']\/\>/i,"*$2*");
}

Целью этой замены является получение innerHTML из contentEditable divв функции обработчика ключей и замените каждый тег img именем файла.Эта замена необходима в моем случае, чтобы знать, превышает ли замещаемый текст максимальную длину, разрешенную для редактируемого div.

function keyupHandler(event) {
  var myEditableDiv = document.getElementById("editableDiv");
  const currentText = getReplacedText(myEditableDiv.innerHTML);
  if (currentText.length >= 750) { //750 is the max length
    event.preventDefault();
  }
}

Например, требуемый вывод для abc <img src="assets\test\1F619.png"> def будет abc *1F619* def

Когда я не использую getReplacedText, у меня нет проблем с производительностью.Не могли бы вы посоветовать мне лучший подход или лучшее использование регулярного выражения?

Это пример текста, который нужно заменить, когда производительность начинает ухудшаться:

dsd<img src="assets\test\1F619.png"/><img src="assets\test\1F619.png"/><img src="assets\test\1F629.png"/><img src="assets\test\1F630.png"/>sdfsdfsdffsdf<img src="assets\test\1F629.png"/>sdfsdsdfsdf<img src="assets\test\1F627.png"/><img src="assets\test\1F631.png"/>sdfsdfsdf<img src="assets\test\1F631.png"/>sdfsdfsdf<img src="assets\test\1F632.png"/>sdfsdfs<img src="assets\test\1F629.png"/><img src="assets\test\1F629.png"/>sdfs<img src="assets\test\1F631.png"/>df<img src="assets\test\1F632.png"/>sdfsdfsdf

Ответы [ 3 ]

2 голосов
/ 04 июля 2019

Избегайте использования регулярных выражений для разбора HTML. Вместо этого используйте DOMParser - найдите <img> теги и замените их текстовым узлом, содержащим только последнюю часть src:

const input = String.raw`dsd<img src="assets\test\1F619.png"><img src="assets\test\1F619.png"><img src="assets\test\1F629.png"><img src="assets\test\1F630.png">sdfsdfsdffsdf<img src="assets\test\1F629.png">sdfsdsdfsdf<img src="assets\test\1F627.png"><img src="assets\test\1F631.png">sdfsdfsdf<img src="assets\test\1F631.png">sdfsdfsdf<img src="assets\test\1F632.png">sdfsdfs<img src="assets\test\1F629.png"><img src="assets\test\1F629.png">sdfs<img src="assets\test\1F631.png">df<img src="assets\test\1F632.png">sdfsdfsdf`;
const doc = new DOMParser().parseFromString(input, 'text/html');
doc.querySelectorAll('img[src]').forEach((img) => {
  img.replaceWith(' ' + img.src.match(/[^\/]+(?=\.png$)/)[0] + ' ');
});
console.log(doc.body.innerHTML);
2 голосов
/ 04 июля 2019

Вам не нужен DOM для анализа HTML-тегов !!!

Самый быстрый способ сделать это, и он не захлебнется, возможно, искаженным html.

Найти

/<img(?=\s)(?=(?:[^>"']|"[^"]*"|'[^']*')*?\ssrc\s*=\s*(?:(['"])(?:(?!\1)[\S\s])*?((?:(?!\1|\\)[\S\s])*?)\.png\s*\1))\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+>/

Заменить *$2*

https://regex101.com/r/bCYXV1/1

Объяснил

                        # Begin 'img' tag
 < img
 (?= \s )
 (?=                    # Asserttion (a pseudo atomic group)
      (?: [^>"'] | " [^"]* " | ' [^']* ' )*?
      \s src \s* = \s*       # src attribute
      (?:
           ( ['"] )               # (1), Quote

           (?:
                (?! \1 )
                [\S\s] 
           )*?
           (                      # (2 start)
                (?:
                     (?! \1 | \\ )
                     [\S\s] 
                )*?
           )                      # (2 end)
           \.png                  # find the 'png' file
           \s* 
           \1          
      )
 )
                        # Have the png file, just match the rest of tag
 \s+ 
 (?: " [\S\s]*? " | ' [\S\s]*? ' | [^>]? )+

 >                      # End img tag

var input = "dsd<img src=\"assets\\test\\1F619.png\"><img src=\"assets\\test\\1F619.png\"><img src=\"assets\\test\\1F629.png\"><img src=\"assets\\test\\1F630.png\">sdfsdfsdffsdf<img src=\"assets\\test\\1F629.png\">sdfsdsdfsdf<img src=\"assets\\test\\1F627.png\"><img src=\"assets\\test\\1F631.png\">sdfsdfsdf<img src=\"assets\\test\\1F631.png\">sdfsdfsdf<img src=\"assets\\test\\1F632.png\">sdfsdfs<img src=\"assets\\test\\1F629.png\"><img src=\"assets\\test\\1F629.png\">sdfs<img src=\"assets\\test\\1F631.png\">df<img src=\"assets\\test\\1F632.png\">sdfsdfsdf";
console.log(input.replace(/<img(?=\s)(?=(?:[^>"']|"[^"]*"|'[^']*')*?\ssrc\s*=\s*(?:(['"])(?:(?!\1)[\S\s])*?((?:(?!\1|\\)[\S\s])*?)\.png\s*\1))\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+>/g 
,"\n*$2*"));
0 голосов
/ 04 июля 2019

Я предполагаю, что, возможно, это простое выражение в режиме s может просто выполнить эту работу здесь:

 <img src=["']\s*(\S+.png)\s*["']\s*>

или, если мы не собираем изображение,

<img src=["']\s*\S+.png\s*["']\s*>

было бы достаточно.

DEMO

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...