我正在尝试使用此代码在java中使用regex匹配此<a href="**something**">
:
Pattern regex = Pattern.compile("<([a-z]+) *[^/]*?>");
Matcher matcher = regex.matcher(string);
string= matcher.replaceAll("");
我对正则表达式并不熟悉。我究竟做错了什么?感谢
答案 0 :(得分:4)
如果您只想找到可以使用的开始标记:
"<a(?=[>\\s])[^>]*>"
如果您尝试获取href属性,最好使用:
"<a\\s+[^>]*href=(['\"])(.*?)\\1[^>]*>"
这将捕获到捕获组2的链接。
答案 1 :(得分:4)
为了让您了解为什么人们总是说“不要尝试使用正则表达式解析HTML”,这里有一个用于匹配<a>
标记的简化正则表达式:
<\s*a(?:\s+[a-z]+(?:\s*=\s*(?:[a-z0-9]+|"[^"]*"|'[^']*'))?)*\s*>
实际上可以将标签与正则表达式匹配。它并不像大多数人所期望的那么容易。
另一方面,所有HTML都不是“常规”,所以你不能用正则表达式来做。 (许多/大多数语言中的“正则表达式”支持实际上比“常规”更强大,但很少有足够强大的功能来处理HTML中的平衡结构。)
以下是上述表达式的细分:
<\s* < and possibly some spaces
a "a"
(?: 0 or more...
\s+ some spaces
[a-z]+ attribute name (simplified)
(?: and maybe...
\s*=\s* an equal sign, possibly with surrounding spaces
(?: and one of:
[a-z0-9]+ - a simple attribute value (simplified)
|"[^"]*" - a double-quoted attr value
|'[^']*' - a single quoted atttr value
)
)?
)*
\s*> possibly more spaces and then >
(每组开头的评论也谈到了运营商 小组的结尾,甚至小组。)
这里可能有其他简化 - 我是从这里写的 记忆,而不是规范。即使您按照规范遵循该规范,浏览器也更容错,并且会接受各种无效输入。
答案 2 :(得分:3)
你可以匹配:
"<a[^>]*>"
如果*
在java中是“贪婪的”(我认为是这样,这是正确的)
但是由于空格,你无法将< a whatever="foo" >
与之匹配。
虽然以下情况比较好,但理解起来比较复杂:
"<\\s*a\\s+[^>]*>"
(需要双\\
,因为\
是java字符串中的特殊字符串)
它在a
之后和之前至少有一个空格处理可选空格。
因此,您不匹配不是正确标签的<abcdef>
。
(我假设你的标签在一行中被隔离,而你没有使用多线模式。否则它会变得复杂得多。)
你的上一个*[^/]*?>
似乎有点奇怪,也许它不起作用。
好的,让我们来看看你在做什么:
<([a-z]+) *[^/]*?>
<([a-z]+)
匹配包含<
后跟[a-z]至少一次的内容。这用括号分组。
现在您使用*
,这意味着定义的组([a-z])*
可能会多次出现。
[^/]*
这意味着现在匹配所有内容,但是/
或者没有(因为*
)
问号是错的,不知道如何解释。
最后一个字符>
与最后一个元素匹配,必须出现。
总而言之,你的表达是错误的,不能正常工作:)
看看:http://www.regular-expressions.info/
这是一个很好的起点。