Как очистить теги 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
Лучшим способом обычно является принудительное использование <
до <
и >
до >
. Таким образом, вы не делаете предположений о характере сообщения. Кто-то может говорить о <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, '<,>', '<,>')>
</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 "< [^ > <] * > " удалит все теги и символы внутри этих тегов и не удалит отдельные теги, такие как < или > , который может использоваться как меньше или больше символа в строке