Java Regex Pattern Matcher用重复替换组

时间:2014-02-20 22:52:11

标签: java html regex pattern-matching replaceall

我有以下情况, 我需要改变,

<a href="ab/xyz" onclick="ab/123"></a>

<a href="pq/xyz" onclick="pq/123"></a>
每当“ab”出现在html标签的属性值中时,

基本上将“ab”替换为“pq”

我写了以下正则表达式,

(<[^>]+)((=")(ab)([^>/"]*"))+([^>].*>)

我正在做replaceAll

if(matcher.find())
matcher.ReplaceAll($1$3pq$4$5)

上面的代码只替换了每个标签的一个属性值,即使我的正则表达式中有重复运算符而且我正在执行ReplaceAll

如果我将“if”条件更改为while循环,那么它会更改所有属性,基本上每次迭代1个属性

有没有办法在没有循环的情况下替换所有属性值中的所有匹配项?

解决方案:即使没有重复运算符,一个愚蠢的正则表达式也在做这个技巧。问题是我匹配整个标签。

1 个答案:

答案 0 :(得分:0)

它只替换了一次出现,因为最后的.*与你的搅拌的整个长度匹配(好吧,直到最后>的所有内容,但很可能是文档的结尾因为它将以html>结束 - 并且背后没有其他匹配。

Java支持前瞻和后瞻,我们需要那些才能使它工作。基本上,前瞻告诉Java“只有在匹配后跟着什么匹配才匹配,但不管是匹配本身的一部分”。 Lookbehinds是相同的,只是在比赛之前必须有的东西。不幸的是,Java在lookbehinds中不支持*+,所以它们有点棘手,但它应该有效:

([^>]*?="[^"]*?)ab(?=[^<]*>)

将其替换为$1pq

我测试了它,它可以工作 - 但只替换每个属性(第一个)中的一个ab。如果你在一个属性中有多个ab并且所有shoudl都被替换,我认为没办法(没有适当的lookbehinds)

请注意,这是假设有效的HTML - 它可能会在无效的HTML上产生意外结果。