当前位置: 首页 > 面试题库 >

如何过滤除特定白名单之外的所有HTML标签?

裴俊智
2023-03-14
问题内容

这是用于.NET。设置了IgnoreCase,未设置MultiLine。

通常我在正则表达式方面很体面,也许我的咖啡因含量低…

允许用户输入HTML编码的实体(<lt;,<amp;等),并使用以下HTML标签:

u, i, b, h3, h4, br, a, img

允许自动关闭
,带有或不带有额外的空间,但不是必需的。

我想要:

  1. 除去上面列出的那些标记之外的所有开始和结束HTML标记。
  2. 从其余标签中删除属性, 锚点可以具有href。

到目前为止,我的搜索模式(替换为空字符串):

<(?!i|b|h3|h4|a|img|/i|/b|/h3|/h4|/a|/img)[^>]+>

除了开始和结束标签,这 似乎 正在剥离所有标签,但是存在三个问题:

  1. 必须包含每个允许标签的结束标签版本是很丑陋的。
  2. 属性得以保留。可以一次更换吗?
  3. 标签 开始 允许的标签名漏网之鱼。例如,“ ”和“

以下建议的模式不会去除没有属性的标记。

</?(?!i|b|h3|h4|a|img)\b[^>]*>

如下所述,“>”在属性值中是合法的,但是可以肯定地说我将不支持。另外,将没有CDATA块等需要担心的问题。只是一些HTML。

漏洞的答案是迄今为止最好的答案,谢谢!这是他的模式(希望PRE对我更有效):

static string SanitizeHtml(string html)
{
    string acceptable = "script|link|title";
    string stringPattern = @"</?(?(?=" + acceptable + @")notag|[a-zA-Z0-9]+)(?:\s[a-zA-Z0-9\-]+=?(?:([""']?).*?\1?)?)*\s*/?>";
    return Regex.Replace(html, stringPattern, "sausage");
}

我认为仍可以对此答案进行一些小调整:

  1. 我认为可以对此进行修改以捕获简单的HTML注释(那些自身不包含标签的注释),方法是在“ acceptable”变量中添加“!-”,并对表达式的末尾进行少量更改以允许可选的尾随“ \ s–”。

  2. 我认为,如果属性之间存在多个空格字符(例如:格式很重的HTML,其中包含换行符和属性之间的制表符),则这会中断。

编辑2009-07-23: 这是我使用的最终解决方案(在VB.NET中):

 Dim AcceptableTags As String = "i|b|u|sup|sub|ol|ul|li|br|h2|h3|h4|h5|span|div|p|a|img|blockquote"
 Dim WhiteListPattern As String = "</?(?(?=" & AcceptableTags & _
      ")notag|[a-zA-Z0-9]+)(?:\s[a-zA-Z0-9\-]+=?(?:([""']?).*?\1?)?)*\s*/?>"
 html = Regex.Replace(html, WhiteListPattern, "", RegExOptions.Compiled)

需要注意的是,A标签的HREF属性仍然被清除,这是不理想的。


问题答案:

这是我为此任务编写的函数:

static string SanitizeHtml(string html)
{
    string acceptable = "script|link|title";
    string stringPattern = @"</?(?(?=" + acceptable + @")notag|[a-zA-Z0-9]+)(?:\s[a-zA-Z0-9\-]+=?(?:(["",']?).*?\1?)?)*\s*/?>";
    return Regex.Replace(html, stringPattern, "sausage");
}

编辑:由于某种原因,我将对先前答案的更正发布为单独的答案,因此我在此处进行合并。

我会解释一下正则表达式,因为它有点长。

第一部分与右方括号匹配,并使用0或1斜杠(如果它是结束标记)。

接下来,您将看到一个if-then构造,并具有前瞻性。(?(?= SomeTag)then |
else)我正在检查字符串的下一部分是否是可接受的标签之一。您可以看到我将regex字符串与可接受的变量连接在一起,该变量是由竖线分隔的可接受的标记名,以便任何术语都可以匹配。如果匹配,则可以看到我输入了“
notag”一词,因为没有标签可以匹配它,如果可以接受,我想不加理会。否则,我将转到其他部分,在该部分我会匹配任何标签名称[az,AZ,0-9] +

接下来,我想匹配0个或多个属性,这些属性假定为attribute =“
value”形式。所以现在我将代表属性的那一部分分组,但是我使用?:来防止为速度而捕获该组:(?:\ s [az,AZ,0-9,-] + =?(?:([“
“,’]?)。 ?\ 1?))

在这里,我从标签和属性名称之间的空白字符开始,然后匹配属性名称:[az,AZ,0-9,-] +

接下来,我匹配一个等号,然后再引用一个。我对报价进行了分组,以便将其捕获,以后可以\
1进行反向引用以匹配相同类型的报价。在这两个引号之间,您可以看到我使用句点来匹配任何内容,但是我使用的是惰性版本?而不是贪婪的版本,因此它将仅与将终止该值的下一个引号匹配。

接下来,我们在用圆括号括起来的组之后放一个*,以便它可以匹配多个属性/值组合(或不匹配)。最后,我们用\
s匹配一些空格,并在xml样式自闭标签的标签中将0或1的结尾斜杠匹配。

您可以看到我正在用香肠替换标签,因为我饿了,但是您也可以用空字符串替换它们以清除它们。



 类似资料:
  • 我需要为我的QGIS项目加载几个矢量层,这样我就可以在每个层中测试我的脚本的每个功能。然而,最后我想只做一两层兴趣,而放弃其他的,所以我想自动做。 我用一些层成功地做到了这一点,但有一层给我带来了问题,我还没有弄清楚原因。 这里有一些代码: 加载层(几乎可以肯定,这不是问题): 现在,我创建了这个函数来删除所有加载的层,除了我想使用的层。,这仅仅是因为我试图理解这个问题。 然后,我创建了一个新的层

  • 问题内容: 我已经看到很多表达式可以删除一个特定的标签(或许多指定的标签),一个可以删除除一个特定标签之外的所有标签,但是我没有找到一种方法来删除其中除许多除外(即所有除外)之外的所有标签。 PHP。我对正则表达式不是很满意,所以我需要帮助。:) 谢谢! 问题答案: 确实做到这一点。

  • 我让用户提交一些文本(包括随机的html图像链接),然后我尝试从文本中的图像创建一个基本的BBCode[img][/img]标记。 我目前的测试方式如下: 字符串(取自随机论坛):

  • 问题内容: 我正在尝试获取2 h1标签之间的所有html。实际的任务是根据h1(heading 1)标签将html分成几帧。 感谢任何帮助。 谢谢苏尼尔 问题答案: 如果要获取和处理两个连续标签之间的所有元素,则可以处理同级对象。这是一些示例代码:

  • 问题内容: 我想删除指定字符或一组字符之前的所有字符(例如): 现在,我想删除以前的(或更具体地说是)。有什么建议? 问题答案: 使用。只需匹配所有字符,然后将匹配的字符替换为。

  • 问题内容: 我在带有一些中间件功能的node.js中使用Express框架: 我可以将函数与附加参数一起使用,以仅在特定路径上使用此中间件: 是否可以使用path变量,以便将中间件用于除特定路径(即根路径)以外的所有路径? 我在想这样的事情: 因此,总是调用除根路径以外的其他路径。 问题答案: 我会将checkUser中间件添加到我的除首页之外的所有路径中。 要么 您可以使用下划线扩展它,以在未经