【问题标题】:How can I clean HTML tags out of a ColdFusion string?如何从 ColdFusion 字符串中清除 HTML 标签?
【发布时间】:2010-11-01 12:46:15
【问题描述】:

我正在寻找一种从 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。

【问题讨论】:

    标签: regex coldfusion rss html-parsing coldfusion-8


    【解决方案1】:

    免责声明 我强烈主张使用适当的解析器(而不是正则表达式)来解析 HTML。然而,这个问题不是关于解析 HTML,而是关于销毁它。对于超出此范围的所有任务,请使用解析器。


    我认为你的正则表达式很好。只要从输入中删除所有HTML标签,使用像你这样的正则表达式是安全的。

    其他任何事情都可能比它的价值更麻烦,但你可以编写一个小函数,逐个字符地循环字符串并删除标记括号内的所有内容 - 例如:

    • 一遇到“&lt;”字符就打开“inTag”标志,
    • 一遇到“&gt;”就关掉
    • 只要标志关闭,就将字符复制到输出字符串
    • 为了提高性能,请使用 StringBuilder Java 对象而不是字符串连接

    对于应用程序的高需求部分,这可能比正则表达式更快。但是正则表达式很干净而且可能足够快。

    也许这个修改过的正则表达式对你有一些好处:

    <[^>]*(?:>|$)
    
    • 在字符串末尾捕获未闭合的标签
    • [^&gt;]* 优于 (.|\n)

    当模式中没有实际字母时,不需要使用REReplaceNoCase()。不区分大小写的正则表达式匹配比区分大小写要慢。

    【讨论】:

    • 我发现 ]*> 作为可能的修改正则表达式。你的后半部分有什么优势?
    • 正如我所说:它在字符串的末尾捕获未闭合的标签。 “(?:>|$)” 读作“结束标记括号或字符串的结尾”。正则表达式的其余部分等同于您找到的替代方法。 "[^>]*" 通常比 "(.|\n)*?" 更值得推荐,因为它更明确而且速度更快。
    • 我建议做第二遍将 与 >,因为你可能有一些剩菜。
    • 同意。好吧,想想看,有了这个正则表达式,就不会有任何左尖括号了。如果输入真的很邪恶,可能会关闭。这些可以用“>”代替。 “
    【解决方案2】:

    最好的方法通常是将&amp;lt; 强制转换为&amp;lt; 并将&amp;gt; 强制转换为&amp;gt;。这样,您就不会对消息的性质做出假设。有人可能在谈论&lt;tags&gt; 或试图成为&lt;&lt;expressive&gt;&gt; 或描述击键&lt;Ctrl&gt;+C 或使用数学1 &lt; x &gt; 3。即使是表情符号也可以触发正则表达式&lt;8P X&gt;

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

    【讨论】:

    • @SpliFF:关于“即使是表情也可以触发正则表达式”——不,他们不能。它们将被编码为“<8P”。
    • 是的,他说他的数据来自 RSS 提要。如果提要是正确的,那么唯一的 将来自标签,其他的将是 <和>。源提要很可能格式错误,但这将是提供者的问题(这可能会弄乱任何提要解析器)。
    • ]]> 在 RSS 提要描述中无效吗?
    • @Peter:大多数 RSS 阅读器会将其解释为 HTML,并且由于没有“this”标签,因此您的结果可能因阅读器而异。这将是 bold, x < 5 ]]> 使用 CDATA,或者不使用 CDATA,您实际上必须进行双重编码,即:<b>bold</b>, x &lt; 5
    • Kip,我的意思是,使用 CDATA,您可能再次处理非 XML HTML,这会将非标签 带回图片中。
    【解决方案3】:

    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/etc 中的选项。

    【讨论】:

    • 啊,船编程:)
    【解决方案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)

        正则表达式“”将删除所有标签和这些标签内的字符,并且不会删除像这样的单个标签,它们可以用作小于或大于字符串中的符号

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-24
          • 2014-11-16
          • 1970-01-01
          • 2012-08-07
          • 1970-01-01
          • 1970-01-01
          • 2013-02-24
          相关资源
          最近更新 更多