用于查找HTML标记及其内容的正则表达式的否定-java
我在uni做一个项目,我必须使用regex清理一些HTML代码(我知道,这不是最好的方法…) 机构的投入:用于查找HTML标记及其内容的正则表达式的否定-java,java,html,regex,regex-negation,Java,Html,Regex,Regex Negation,我在uni做一个项目,我必须使用regex清理一些HTML代码(我知道,这不是最好的方法…) 机构的投入: <h1>This is heading 1</h1> <h2 style="color: aqua">This is heading 2</h2> <h3>This is heading 3</h3> <p>This is a paragraph.</p> <p>This is an
<h1>This is heading 1</h1>
<h2 style="color: aqua">This is heading 2</h2>
<h3>This is heading 3</h3>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<a href="https://www.w3schools.com">This is a link</a>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
它工作,但现在我必须否定它,并删除所有的标签和内容,除了那些在
我试过这个,但不起作用:
`...[?!h3|ul|p]...`
本例的预期结果:
<h3>This is heading 3</h3>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<ul>
</ul>
这是标题3
这是一段
这是另一段
我真的不太明白消极前瞻以及如何将其应用于我的问题,因此我将感谢您提供的任何建议。您可能希望提取您希望在所需输出中的内容。此表达式可能是更好的选择,如果您愿意,可以对其进行修改:
(<(p|h3.*)>.*<\/(.*)>)|(<(ul.*)>[\s\S]*<\/(ul)>)
(.*)|([\s\s]*)
它有两个组,一个用于p和h3,另一个用于ul,您可以将它们包装到另一个捕获组:
((<(p|h3.*)>.*<\/(.*)>)|(<(ul.*)>[\s\S]*<\/(ul)>))
((.*)|([\s\s]*))
正则表达式
如果这不是您想要的表达式,您可以在中修改/更改表达式
正则表达式电路
您还可以在以下位置可视化您的表达式:
Java测试
import java.util.regex.Matcher;
导入java.util.regex.Pattern;
最后一个字符串regex=“(.*)|”([\\s\\s]*)”;
final String=“这是标题1\n”
+“这是标题2\n”
+“这是标题3\n”
+“这是一个段落。\n”
+“这是另一段。\n”
+“\n”
+“\n”
+“- 咖啡
\n”
+“- 茶
\n”
+“- 牛奶
\n”
+“
”;
最终模式=Pattern.compile(regex,Pattern.MULTILINE);
final Matcher Matcher=pattern.Matcher(字符串);
while(matcher.find()){
System.out.println(“完全匹配:+matcher.group(0));
对于(int i=1;i{
log(`Found match,group${groupIndex}:${match}`);
});
}
您尝试使用的负面前瞻需要写成(?!(?:h3 | ul | p)\b)
,它不会选择h3
或ul
或p
标记。注意在它后面使用单词boundary\b
,以便拒绝这些标记的精确匹配。除了移除那些标记,你还必须移除移除那些标记后留下的空白,因此你需要使用的正则表达式是这样的
\h*<(?!(?:h3|ul|p)\b)([^>]+).*?>[\w\W]*?</\1>\s*
产出
Before:
<h1>This is heading 1</h1>
<h2 style="color: aqua">This is heading 2</h2>
<h3>This is heading 3</h3>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<a href="https://www.w3schools.com">This is a link</a>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
After:
<h3>This is heading 3</h3>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<ul>
</ul>
之前:
这是标题1
这是标题2
这是标题3
这是一段
这是另一段
- 咖啡
- 茶
- 牛奶
之后:
这是标题3
这是一段
这是另一段
“我尝试了这个,但没有成功:…[?!h3 | ul | p]…”负匹配的语法是(?!xxx)
,称为“零宽度负前瞻”。请参阅以获取显示语法的javadoc和说明。仅供参考:在Java中,不需要转义/
,因为这不是特殊字符。在语言中,它只是一个特殊字符,用/
引用regex,即regex写为/xxx/
,除非递归地应用regex,否则它不会删除允许标记中不允许的标记。它也不会将测试保留在任何标签之外。例如,由于
标记是不允许的,因此应该删除它们,如问题中的“期望结果”所示,但您的解决方案保留了它们。@Emma yep,这是一个相当大的问题,因为当我使用您的方法时,我需要只提取允许的标记,而不提取(可能不允许的)内的标记。。。你知道怎么做吗?非常感谢你的评论,我已经试过了。
\h*<(?!(?:h3|ul|p)\b)([^>]+).*?>[\w\W]*?</\1>\s*
String s = "<h1>This is heading 1</h1>\r\n" +
"<h2 style=\"color: aqua\">This is heading 2</h2>\r\n" +
"<h3>This is heading 3</h3>\r\n" +
"<p>This is a paragraph.</p>\r\n" +
"<p>This is another paragraph.</p>\r\n" +
"<a href=\"https://www.w3schools.com\">This is a link</a>\r\n" +
"<ul>\r\n" +
" <li>Coffee</li>\r\n" +
" <li>Tea</li>\r\n" +
" <li>Milk</li>\r\n" +
"</ul>";
System.out.println("Before:\n" + s);
System.out.println("\nAfter:\n" + s.replaceAll("\\h*<(?!(?:h3|ul|p)\\b)([^>]+).*?>[\\w\\W]*?</\\1>\\s*", ""));
Before:
<h1>This is heading 1</h1>
<h2 style="color: aqua">This is heading 2</h2>
<h3>This is heading 3</h3>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<a href="https://www.w3schools.com">This is a link</a>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
After:
<h3>This is heading 3</h3>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<ul>
</ul>