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).+\)~
我正在尝试更新 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).+\)~