为什么不是';t java.util.regex.matcher不匹配此字符串中的所有实例?

为什么不是';t java.util.regex.matcher不匹配此字符串中的所有实例?,java,regex,matcher,replaceall,Java,Regex,Matcher,Replaceall,我有以下代码: 不幸的是,这段代码并没有达到我期望的效果,即用字符串替换替换正则表达式的所有匹配项。我们基本上是用绝对URL替换CSS和HTML中的相对URL。它似乎只是取代了第一次出现,给予 div#header { background-image: url('http://www.google.ca/images/header-background.jpg'); } div#header { background-image: url('images/header-background.j

我有以下代码:

不幸的是,这段代码并没有达到我期望的效果,即用字符串替换替换正则表达式的所有匹配项。我们基本上是用绝对URL替换CSS和HTML中的相对URL。它似乎只是取代了第一次出现,给予

div#header { background-image: url('http://www.google.ca/images/header-background.jpg'); } div#header { background-image: url('images/header-background.jpg'); }
href="http://www.google.ca/wtfguys.css" href="wtfguys.css"

作为输出。有什么建议吗?

*
太贪婪了。匹配器将
wtfguys.css”href=“wtfguys.css
捕获为
$2
,而不是
wtfguys.css
。您可以改用
*?
[^\“]*
,因为URL中甚至没有转义引号。本期参考资料解释了几个选项(包括Wiktor提到的选项):。

您正在使用试图匹配单引号和双引号属性值的regexp。问题是,您可能会匹配截断的值,因为这两种模式都无法确保开始引号与结束引号匹配。此外,该引号应该在值本身中丢失

因此,将开始引号包装到捕获组中,使用Backreference作为结束分隔符,并将Backreference作为先行标记的替代项添加到标记中。然后,修复替换模式,因为Backreference的顺序将更改

private static final Pattern resourceURLCSS     = Pattern.compile("url\\((['\"])((?:(?!://|\\1).)*)\\1\\)");
private static final Pattern resourceURLHTML    = Pattern.compile("(href|src|url)=(['\"])((?:(?!://|\\2).)*)\\2");

public static String makeCSSURLsAbsolute(String input, String baseURL)
{
    Matcher matcher     = resourceURLCSS.matcher(input);
    return matcher.replaceAll("url('"+baseURL+"$2')");
}
public static String makeHTMLURLsAbsolute(String input, String baseURL)
{
    Matcher matcher     = resourceURLHTML.matcher(input);
    return matcher.replaceAll("$1=\""+baseURL+"$3\"");
}

请看

,解决方案可能是在
*
之后添加一个
,使其成为非贪婪的。不,我认为调和贪婪标记应该被修复,它不仅仅是关于懒惰或贪婪的量词。否则,就不会有
[\'\“]
了。另一个捕获组、一个反向引用和一个反向前瞻中的替代项是必需的。不需要支持转义序列,它们不是C字符串。
private static final Pattern resourceURLCSS     = Pattern.compile("url\\((['\"])((?:(?!://|\\1).)*)\\1\\)");
private static final Pattern resourceURLHTML    = Pattern.compile("(href|src|url)=(['\"])((?:(?!://|\\2).)*)\\2");

public static String makeCSSURLsAbsolute(String input, String baseURL)
{
    Matcher matcher     = resourceURLCSS.matcher(input);
    return matcher.replaceAll("url('"+baseURL+"$2')");
}
public static String makeHTMLURLsAbsolute(String input, String baseURL)
{
    Matcher matcher     = resourceURLHTML.matcher(input);
    return matcher.replaceAll("$1=\""+baseURL+"$3\"");
}