Как очистить теги HTML из строки ColdFusion?

Я ищу быстрый способ анализировать теги HTML из строки ColdFusion. Мы тянем RSS-канал, который может иметь что-то в нем. Затем мы делаем некоторые манипуляции с информацией, а затем выплевываем ее обратно в другое место. В настоящее время мы делаем это с регулярным выражением. Есть ли лучший способ сделать это?

<cfloop from="1" to="#ArrayLen(myFeed.item)#" index="i">
  <cfset myFeed.item[i].description.value = 
   REReplaceNoCase(myFeed.item[i].description.value, '<(.|\n)*?>', '', 'ALL')>
</cfloop>

Мы используем ColdFusion 8.

Ответ 1

Отказ от ответственности Я - ярый сторонник использования правильного анализатора (вместо регулярного выражения) для анализа HTML. Однако этот вопрос заключается не в разборе HTML, а в его уничтожении. Для всех задач, выходящих за рамки этого, используйте синтаксический анализатор.


Я думаю, что ваше регулярное выражение хорошее. Пока нет ничего, кроме удаления всех тэгов HTML из ввода, использование регулярного выражения, подобного вашему, безопасно.

Что-нибудь еще, вероятно, будет более сложным, чем это стоит, но вы можете написать небольшую функцию, которая повторяется через строку char -by- char один раз и удаляет все, что находится в скобках тегов — например:

  • включите флаг "inTag", как только вы столкнетесь с символом "<",
  • выключите его, как только вы столкнетесь с ">"
  • копировать символы в выходную строку, пока флаг выключен.
  • для производительности используйте объект Java StringBuilder вместо конкатенации строк

Для части приложения с высоким спросом это может быть быстрее, чем регулярное выражение. Но регулярное выражение чистое и, вероятно, достаточно быстрое.

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

<[^>]*(?:>|$)
  • обнаруживает закрытые теги в конце строки
  • [^>]* лучше, чем (.|\n)

Использование REReplaceNoCase() не требуется, если в шаблоне нет фактических букв. Совместимость с регулярным выражением, нечувствительным к регистру, медленнее, чем выполнение этого случая с чувством.

Ответ 2

HTML не является обычным языком, поэтому использование регулярных выражений на (неконтролируемом) HTML - это то, что нужно делать с большой осторожностью (если вообще).

Рассмотрим, например, следующий допустимый сегмент HTML:

<img src="boat.jpg" alt="a boat" title="My boat is > everything! I <3 my boat!">

Вы заметите, как синтаксический ярлык задыхается от этого - как и предлагаемое существующее регулярное выражение.

Если вы не можете быть уверены, что строка, которую вы обрабатываете, не будет содержать HTML-код, подобный вышеизложенному, вы должны избегать принятия предположений/компромиссов, которые заставят вас сделать один/чистый маршрут регулярного выражения.

(Примечание. Эта же проблема относится и к предлагаемому методу char -by- char).


Чтобы решить вашу проблему, вы должны использовать парсер DOM для синтаксического анализа вашей строки в HTML-объект, циклический переход через каждый элемент и преобразование в текст.

Если у вас есть действительный XHTML, вы можете использовать CF XmlParse() для создания объекта, который вы затем можете зацикливать. Если это может быть не XML-XML, то нет встроенной опции с CF8, поэтому вам придется исследовать параметры в Java/etc.

Ответ 3

Лучшим способом обычно является принудительное использование < до &lt; и > до &gt;. Таким образом, вы не делаете предположений о характере сообщения. Кто-то может говорить о <tags> или пытается быть <<expressive>> или описывать нажатие клавиши <Ctrl>+C или использовать математику 1 < x > 3. Даже смайлики могут вызвать регулярное выражение <8P X>

<cfloop from="1" to="#ArrayLen(myFeed.item)#" index="i">
    <cfset myFeed.item[i].description.value = ReplaceList(myFeed.item[i].description.value, '<,>', '&lt;,&gt;')>
</cfloop>

Ответ 4

cflib является вашим другом: stripHTML

Ответ 5

Я использую это:

REReplaceNoCase(text, "<[^[:space:]][^>]*>", "", "ALL");

В 99% случаев он работает нормально.

Ответ 6

<cfset a = "<b><font color = 'red'>(PCB) <1 ppm </font></b>">

<cfset b = REReplaceNoCase(a, "<[^><]*>", '', 'ALL')>

<cfdump var="#b#">

выход b = "(PCB) < 1 ppm"

Regex "< [^ > <] * > " удалит все теги и символы внутри этих тегов и не удалит отдельные теги, такие как < или > , который может использоваться как меньше или больше символа в строке