Java replaceAll 用正则表达式只替换第一个实例

Java replaceAll with regex only replacing first instance

我正在尝试更新 CSS 字符串中的所有 url,而我的正则表达式似乎只得到第一个。我想得到类似的东西:

url("file")
url('file');
url(file);

我还想排除 url 是数据的东西:

url("data: ...");
url('data: ...');
url(data: ...);

我写了一些代码来做到这一点,但它只替换了第一个:

String str = ".ff0{font-family:sans-serif;visibility:hidden;}@font-face{font-family:ff1;src:url(f1.woff)format(\"woff\");}.ff1{font-family:ff1;line-height:1.330566;font-style:normal;font-weight:normal;visibility:visible;}@font-face{font-family:ff2;src:url(f2.woff)format(\"woff\");}.ff2{font-family:ff2;line-height:1.313477;font-style:normal;font-weight:normal;visibility:visible;}@font-face{font-family:ff3;src:url(f3.woff)format(\"woff\");}.ff3{font-family:ff3;line-height:1.386719;font-style:normal;font-weight:normal;visibility:visible;}@font-face{font-family:ff4;src:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1IiBoZWlnaHQ9IjUiPgo8cmVjdCB3aWR0aD0iNSIgaGVpZ2h0PSI1IiBmaWxsPSIjOWU5ZTllIj48L3JlY3Q+CjxwYXRoIGQ9Ik0wIDVMNSAwWk02IDRMNCA2Wk0tMSAxTDEgLTFaIiBzdHJva2U9IiM4ODgiIHN0cm9rZS13aWR0aD0iMSI+PC9wYXRoPgo8L3N2Zz4=)format(\"woff\");";
str = str.replaceAll("url\((['\"]?)(?!data)(.*)\1\)","url(someURL/)");
out.println(str);

关于如何解决的任何想法?我想这与正则表达式有关。

您可能想使用非贪婪量词(*? 而不是 *)。

要正确排除 data 条目,还要使用所有格量词来捕获引号:?+ 而不是 ?

因此您的正则表达式应如下所示: url\((['"]?+)(?!data)(.*?)\) 请注意,您可能应该像在示例中那样使用额外的斜杠转义某些字符。

你的.*太贪心了。它捕获到字符串的末尾。请改用 .*?,这将强制引擎捕获尽可能少的字符。

str = str.replaceAll("url\((['\"]?)(?!data)(.*?)\1\)","url(someURL/)");

像这样的东西应该可以工作:

~\((?!.*data).+\)~