Как очистить текст от html тегов и повторяющихся символов (пробелы, переносы,...) на JavaScript?

Как правильно очистить текст от html тегов и повторяющихся символов (пробелы, переносы,...) на JavaScript?

Как  правильно очистить текст от html тегов и повторяющихся символов (пробелы, переносы,...) на JavaScript? Иногда возникает необходимость очистить текст от html тегов и различных повторяющихся символов, как например пробелов и переносов строк. Причин может быть масса. Разработка собственного инструмента. Очистка пользовательских комментариев от вредоносного кода. Предварительная обработка импортируемых текстов. И многое другое.

С одной стороны, задача кажется достаточно простой. В интернете можно найти много готовых решений не только на JavaScript, но и на других языках. С другой стороны, после того, как вы начинаете их использовать, постепенно выявляются различные неучтенные моменты. Например, наличие тегов комментариев может стать неожиданностью для тех, кто использует популярное решение для очистки тегов.

 

Правильная чистка текста от html тегов на JavaScript

Чтобы продемонстрировать проблемы популярных решений для чистки текста от html тегов, воспользуемся следующим текстом:

<script>Вредоносный код<!-- -- > --></script>
< Этого текста не будет, так как текст содержал не &lt;, а его символ
<!-- > Комментарий к тексту, который не должен отображаться -->
&lt;script type="text/javascript" lang="javascript">
Вредоносный код 2
&lt;/script>

Обычная очистка следующим регулярным выражением

text.replace(/<[^>]+>/g, '')

Выдаст следующий результат:

Вредоносный код -->
Комментарий к тексту, который не должен отображаться -->
&lt;script type="text/javascript" lang="javascript">
Вредоносный код 2
&lt;/script>

Не сложно заметить первую проблему, а именно наличие текста, которого, в принципе, не должно быть. Это текст из комментариев. И следом за ней вторую проблему - отсутствие текста, в котором передался символ "<" вместо "&lt;". Конечно, при валидном коде, такой проблемы не должно возникнуть. Но, если вдуматься, то вторую проблему легко воспроизвести. Достаточно в тексте использовать сравнительные выражения, с использованием символов "<" и ">", и передавать на очистку скопированный текст. 

Если первую проблему можно побороть одним простым выражением:

 
text.replace(/<!--(.*?)[-][-][>]/g, '');

То со второй проблемой все несколько сложнее. Необходимо перечислять абсолютно все названия удаляемых тегов. 

var text = "некоторый текст";
text.replace(/<a(.*?)>/gi, '')
.replace(/<[/]\s+a(.*?)>/gi, '');
...
text.replace(/<iframe(.*?)>/gi, '')
.replace(/<[/]\s+iframe(.*?)>/gi, '');

Согласитесь, что такая конструкция уже отличается от простого выражения чистки всех тегов.

Примечание: Конечно, вы можете просто заменять символы на "&lt;" и "&gt;", но тогда вы не сможете очистить текст от html тегов. 

 

Правильная чистка текста от повторяющихся пробелов, переносов и прочих символов на JavaScript 

Очистка текста от повторяющихся пробелов, переносов и прочих символов так же имеет ряд своих проблем. Для их демонстрации возьмем первый текст и добавим в него пару переносов строк и лишних пробелов:

<script>  Вредоносный код<!-- -- > --></script>
< Этого текста не будет, так как текст содержал не &lt;, а его символ
<!-- > Комментарий к тексту, который не должен отображаться -->
&lt;script type="text/javascript" lang="javascript">
     Вредоносный код 2
&lt;/script>

Допустим, вы правильно очистили текст от html тегов. Тогда у вас должен появиться следующий текст:

  Вредоносный код
< Этого текста не будет, так как текст содержал не &lt;, а его символ
&lt;script type="text/javascript" lang="javascript">
    Вредоносный код 2
&lt;/script>

Теперь, необходимо данный текст почистить от лишних символов. И первое, что приходит на ум - это средство для замены всех спецсимволов на пробел:

text.replace(/\s+/g, ' ');

Перед вами появится первая проблема. Весь текст лишился символов переноса строки, а именно '\n'. Поэтому готовый текст будет выглядеть так:

Вредоносный код < Этого текста не будет, так как текст содержал не &lt;, а его символ &lt;script type="text/javascript" lang="javascript"> Вредоносный код 2 &lt;/script>

Да, проблема в отсутствии форматирования, как такового. Для небольших текстов это не страшно, ведь даже без форматирования результат будет достаточно легко восприниматься. Но, как только речь зайдет о большом тексте, то проблема остро встанет. Мало кто захочет читать большие "простыни" текста.

Поэтому, вместо этого простого регулярного выражения, стоит использовать следующую конструкцию:

// Заменяем спецсимвол пробела на реальные пробелы
text = count_char_textarea.value.replace(/&nbsp;/g, ' ');
// Заменяем табуляцию на пробелы
text = text.replace(/[\t]/g, ' ');
// Наконец чистим от дублирующих пробелов
text = text.replace(/[ ]{2,}/g, ' ');
// Заменяем пробелы перед переносами на переносы
text = text.replace(/[\s]+([\r\n])/g, '\r\n');
// Заменяем пробелы после переносов на переносы
text = text.replace(/([\r\n])[\s]+/g, '\r\n');
// Наконец удаляем повторяющиеся переносы
text = text.replace(/[\r\n]{2,}/g, '\r\n');

Теперь, результат сохранит корректность и будет намного легче восприниматься: 

 Вредоносный код
< Этого текста не будет, так как текст содержал не &lt;, а его символ
&lt;script type="text/javascript" lang="javascript">
Вредоносный код 2
&lt;/script>

Тем не менее, видно, что в тексте остаются кодированные спецсимволы. И, обычно, их заменяют следующим кодом:

text.replace(/&lt;/g, '<');
....
text.replace(/&copy;/g, '©');

Применяя код на тексте, получим:

 Вредоносный код
< Этого текста не будет, так как текст содержал не <, а его символ
<script type="text/javascript" lang="javascript">
Вредоносный код 2
</script>

Но, тут то и кроется вторая проблема. В попытке привести код к красивому виду, а именно замене обозначений спецсимволов на их реальный вид, вы создаете потенциальную угрозу. Дело в том, что замена "&lt;" на "<" сделает второй вредоносный код реальной угрозой. Достаточно вставить такой текст как html, и скрипт запустится. Чтобы избежать этой проблемы, необходимо повторно правильно очищать текст от html тегов.

Примечание: Как альтернатива, вы можете ввести себе в привычку наоборот преобразовывать все спецсимволы в их кодированные конструкции, и уже такой текст вставлять как html. Однако, при этом в тексте будет оставаться необходимая конструкция для запуска вредоносного кода, которая по чистой случайности может запуститься на других сайтах, где данная проблема никак не решается.

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

☕ Понравился обзор? Поделитесь с друзьями!

Добавить комментарий / отзыв

Комментарий - это вежливое и наполненное смыслом сообщение (правила).



* Нажимая на кнопку "Отправить", Вы соглашаетесь с политикой конфиденциальности.
Присоединяйтесь
 

 

Программы (Freeware, OpenSource...)