为什么这段代码不会返回“”? 我应该用什么正则表达式替换html文件中的所有标签?
x = x.replaceAll("<.*>", "<h3><a href=\"#\">current community</a></h3>");
谢谢!
答案 0 :(得分:4)
我想删除HTML标记
您可以简单地使用HTML解析库,例如JSoup
。这是一个例子
Document doc =
Jsoup.parse("<html><h3><a href=\"#\">current community</a></h3></html>");
System.out.println(doc.text());
输出:
current community
答案 1 :(得分:3)
我同意其他人试图使用正则表达式来解析HTML是一个坏主意。 (我认为即使你正在做的就是删除标签也是如此;评论和!CDATA
之类的东西会使任何一个简单解决方案的尝试变得复杂。)但是,我认为解释为什么你的解决方案没有用'产生预期的结果(因为这适用于正则表达式更合适的其他情况)。
默认情况下,*
和+
量词是贪心,这意味着它们会匹配尽可能多的字符。因此,在您的示例中:
x = x.replaceAll("<.*>", "<h3><a href=\"#\">current community</a></h3>");
我认为这就是你的意思:
String x = "<h3><a href=\"#\">current community</a></h3>";
x = x.replaceAll("<.*>", "");
当匹配引擎搜索您的模式时,会发现<
为x
的第一个字符。然后它查找可以是任何内容的零个或多个字符的序列,然后是>
。但由于它是一个贪婪的量词,如果它可以选择多个>
,它将选择使.*
与最长可能的字符串匹配的那个。在您的情况下,这意味着它将选择>
,这是x
的最后一个字符。结果是整个字符串被""
替换。
要使其与最小可能的字符串匹配,请添加?
以使其成为“不情愿的量词”:
x = x.replaceAll("<.*?>", "");
另一个解决方案是告诉匹配器在匹配“任何字符”时不要包含>
:
x = x.replaceAll("<[^>]*>", "");
[^>]
表示“匹配除>
之外的任何字符。对于HTML / XML / SGML,我选择的正则表达式不是上述的,因为您不应该使用正则表达式来解析复杂结构那样的。
答案 2 :(得分:2)
免责声明:您不应该使用正则表达式来解析HTML。
但是,如果你坚持,试试
查找:"<(?:(?:/?\\w+\\s*/?)|(?:\\w+\\s+(?:(?:(?:\"[\\S\\s]*?\")|(?:'[\\S\\s]*?'))|(?:[^>]*?))+\\s*/?)|\\?[\\S\\s]*?\\?|(?:!(?:(?:DOCTYPE[\\S\\s]*?)|(?:\\[CDATA\\[[\\S\\s]*?\\]\\])|(?:--[\\S\\s]*?--)|(?:ATTLIST[\\S\\s]*?)|(?:ENTITY[\\S\\s]*?)|(?:ELEMENT[\\S\\s]*?))))>"
替换:“”
<
(?:
(?:
/?
\w+
\s*
/?
)
|
(?:
\w+
\s+
(?:
(?:
(?: " [\S\s]*? " )
| (?: ' [\S\s]*? ' )
)
| (?: [^>]*? )
)+
\s*
/?
)
|
\?
[\S\s]*?
\?
|
(?:
!
(?:
(?:
DOCTYPE
[\S\s]*?
)
| (?:
\[CDATA\[
[\S\s]*?
\]\]
)
| (?:
--
[\S\s]*?
--
)
| (?:
ATTLIST
[\S\s]*?
)
| (?:
ENTITY
[\S\s]*?
)
| (?:
ELEMENT
[\S\s]*?
)
)
)
)
>