Ruby中忽略HTML标签转义HTML实体的解决方案
解决HTML标签保留与实体转义的问题
嘿,这个问题我之前也碰到过!核心难点就是要区分需要保留的HTML标签和需要转义的普通HTML实体,直接用CGI.escape_html肯定不行,因为它会全局转义所有<和>,把你想保留的标签也转成实体了。
我给你两种可行的解决方案,都是基于Ruby环境(因为你用了CGI模块):
方案一:占位符替换法
这个方法思路很直观:先把需要保留的标签临时替换成不会被转义的占位符,转义完其他内容后再替换回来。
require 'cgi' def smart_escape_html(content) # 定义你需要保留的所有HTML标签 allowed_tags = ['<p>', '</p>', '<h1>', '</h1>', '<br/>'] # 为每个允许的标签创建唯一的占位符(避免和内容冲突) tag_placeholders = allowed_tags.each_with_object({}) do |tag, mapping| # 把标签里的特殊字符换成下划线,转成大写作为占位符 placeholder = "__#{tag.gsub(/[<>\/]/, '_').upcase}__" mapping[tag] = placeholder end # 第一步:把内容里的允许标签替换成占位符 temp_content = content.dup tag_placeholders.each { |tag, placeholder| temp_content.gsub!(tag, placeholder) } # 第二步:转义所有剩下的HTML实体 escaped_content = CGI.escape_html(temp_content) # 第三步:把占位符替换回原来的HTML标签 tag_placeholders.each { |tag, placeholder| escaped_content.gsub!(placeholder, tag) } escaped_content end # 测试示例 original_msg = '<p><some message here></p>' puts smart_escape_html(original_msg) # 输出结果:<p><some message here></p>
方案二:拆分内容转义法
这个方法利用正则表达式把内容拆分成「允许的标签」和「普通文本」两部分,只对普通文本部分进行转义,再拼接起来。
require 'cgi' def smart_escape_html(content) # 正则匹配所有需要保留的标签(注意转义特殊字符) allowed_tags_regex = /(<p>|<\/p>|<h1>|<\/h1>|<br\/>)/ # 按允许的标签拆分内容,得到标签和文本交替的数组 content_parts = content.split(allowed_tags_regex) # 遍历数组:如果是允许的标签就保留,否则转义 escaped_parts = content_parts.map do |part| allowed_tags_regex.match?(part) ? part : CGI.escape_html(part) end # 拼接所有部分得到最终结果 escaped_parts.join end # 测试同样有效 original_msg = '<p><some message here></p>' puts smart_escape_html(original_msg) # 输出:<p><some message here></p>
注意事项
- 如果需要保留更多标签,只需要扩展
allowed_tags数组(方案一)或者更新allowed_tags_regex正则(方案二)即可。 - 占位符要尽量独特,避免和你的内容文本重复,比如用
__包裹的大写标识符,基本不会和普通内容冲突。
内容的提问来源于stack exchange,提问作者atta ul mohsin
相关产品推荐
相关产品推荐

