我有一个HTML结束标记的白名单(br
,b
,i
,div
): -
String whitelist = "([^br|^b|^i|^div])";
String endTagPattern = "(<[ ]*/[ ]*)" + whitelist + "(>?).*?([^>]+>)";
...
html = html.replaceAll(endTagPattern, "[r]");
我的测试String
会移除那些不在白名单中的人的结束标记,在这种情况下,为了清楚起见,将其替换为[r]
: -
1. <b>bold</b>, 2. <i>italic</i>, 3. <strong>strong</strong>, 4. <div>div</div>, 5. <script lang='test'>script</script>
1. <b>bold</b>, 2. <i>italic</i>, 3. <strong>strong[r], 4. <div>div</div>, 5. <script lang='test'>script[r]
如果我将strong
添加到此白名单
String whitelist = "([^br|^b|^i|^div|^strong])";
它不仅与strong
结束标记不匹配,还会停止匹配结束script
标记或其他任何标记。
我的问题是,为什么?
答案 0 :(得分:4)
原因是你正在使用一个字符类。在字符类中,除了处理字符范围外,字符的顺序并不重要。
因此,[^br|^b|^i|^div|^strong]
实际上将匹配除以下字符之外的任何字符:
bridvstrong|^
[请注意|
和^
也是如此。
您可以使用[^bridvstrong|^]
并且行为方式相同。
你可能会看一下负向前瞻。
答案 1 :(得分:1)
String whitelist = "([^br|^b|^i|^div])";
使用[]
创建一个字符类。我认为你写了这个,所以你可以使用^
作为“not”,但是字符类在这里是不合适的。在方括号内,|
并不代表“或”;它只是一个文字管道角色。撰写div
与字 div
不匹配,它会匹配三个字符之一,d
,i
或{{1 }}。否定这意味着“匹配除v
,d
或i
之外的所有内容。
该白名单实际上等同于v
- 它匹配的单个字符不是[^bdirv|\^]
,b
,d
,i
,{{1 }},r
或v
。
|
如果您想排除某些匹配项,您需要的是negative lookahead。如果没有方括号,您可以按照预期的方式使用^
作为“或”运算符。