Как очистить теги HTML от строки ColdFusion? - PullRequest
11 голосов
/ 09 июня 2009

Я ищу быстрый способ анализа 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.

Ответы [ 6 ]

15 голосов
/ 09 июня 2009

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


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

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

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

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

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

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

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

7 голосов
/ 09 июня 2009

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 HTML, то в CF8 нет встроенной опции, поэтому вам придется изучить опции в Java / и т. Д.

3 голосов
/ 30 декабря 2013

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

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

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

2 голосов
/ 10 июня 2009

cflib ваш друг: stripHTML

2 голосов
/ 09 июня 2009

Лучшим способом обычно является принуждение < к &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>
0 голосов
/ 03 декабря 2015
<cfset a = "<b><font color = 'red'>(PCB) <1 ppm </font></b>">

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

<cfdump var="#b#">

output b = "(PCB) <1 ppm" </p>

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

...