我正在寻找一种从ColdFusion字符串中解析HTML标记的快捷方法。我们正在提供一个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。
答案 0 :(得分:15)
免责声明我是使用正确的解析器(而不是正则表达式)来解析HTML的激烈倡导者。但是,这个问题不是关于解析 HTML,而是关于销毁它。对于超出该范围的所有任务,请使用解析器。
我认为你的正则表达式很好。只要从输入中删除所有HTML标记,只需使用像你这样的正则表达式就可以了。
其他任何东西都可能比它的价值更麻烦,但你可以写一个小函数,循环遍历字符串char-by-char一次并删除标签括号内的所有内容 - 例如:
<
”字符时立即打开“inTag”标志,>
”对于应用程序的高需求部分,这可能比正则表达式更快。但正则表达式很干净,而且可能足够快。
也许这个修改过的正则表达式对你有一些好处:
<[^>]*(?:>|$)
[^>]*
优于(.|\n)
当模式中没有实际字母时,不需要使用REReplaceNoCase()
。不区分大小写的正则表达式匹配比区分大小写更慢。
答案 1 :(得分:7)
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 /等中的选项。
答案 2 :(得分:3)
我用这个:
REReplaceNoCase(text, "<[^[:space:]][^>]*>", "", "ALL");
99%的案例都可以正常使用。
答案 3 :(得分:2)
最好的方法通常是将<
强制转换为<
,将>
强制转换为>
。这样您就不会对消息的性质做出假设。有人可能在谈论<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 :(得分:2)
答案 5 :(得分:0)
<cfset a = "<b><font color = 'red'>(PCB) <1 ppm </font></b>">
<cfset b = REReplaceNoCase(a, "<[^><]*>", '', 'ALL')>
<cfdump var="#b#">
输出b =“(PCB)<1 ppm”
正则表达式“&lt; [^&gt;&lt;] *&gt;”将删除所有标签和这些标签内的字符,并且不会删除单个标签,例如&lt;或者&gt;可以用作小于或大于字符串
中的符号