我(正则表达式菜鸟)正在尝试对包含某种模式的字符串执行替换操作。例如
AAA-BBB-CCC-{AAA-BBB-AAA-BBB}-CCC-BBB-AAA
在上面我试图替换所有 A
与I
但忽略 A
s 在大括号内。
为此,我可以做的是拆分模式上的整个字符串并执行替换,然后连接字符串。
我想知道正则表达式中是否有更短的方法,以便我可以执行类似的操作
String str = "AAA-BBB-CCC-{AAA-BBB-AAA-BBB}-CCC-BBB-AAA";
str = str.replaceButIgnorePattern("A", "I","\\{(.*?)\\}");
System.out.print(str); //III-BBB-CCC-{AAA-BBB-AAA-BBB}-CCC-BBB-III
图案可以是这样的
包含任意字符
可以位于字符串的开头、中间或末尾
最佳答案
考虑到没有嵌套大括号,解决方案是匹配最接近的 {
和 }
内的子字符串> 并匹配并捕获要替换的模式,然后检查组 1 是否不为空,然后采取相应行动。
在 Java 9+ 中,您可以使用
String text = "AAA-BBB-CCC-{AAA-BBB-AAA-BBB}-CCC-BBB-AAA";
Pattern r = Pattern.compile("\\{[^{}]*}|(A)");
Macher m = r.matcher(text);
String result = m.replaceAll(x -> x.group(1) != null ? "I" : x.group() );
System.out.println( result );
请参阅online demo .
此处,\{[^{}]*}
匹配 {
、除 {
和 } 之外的任何 0+ 个字符
,然后 }
或 (|
) 将 A
捕获到组 1。
旧 Java 版本的等效代码:
String text = "AAA-BBB-CCC-{AAA-BBB-AAA-BBB}-CCC-BBB-AAA";
Pattern r = Pattern.compile("\\{[^{}]*}|(A)");
Matcher m = r.matcher(text);
StringBuffer sb = new StringBuffer();
while (m.find()) {
if (m.group(1) == null) {
m.appendReplacement(sb, m.group(0));
} else {
m.appendReplacement(sb, "I");
}
}
m.appendTail(sb);
System.out.println(sb);
请参阅online Java demo .
您还可以对任何 Java 版本使用通用解决方法:
str = str.replaceAll("A(?![^{}]*})", "I");
其中 (?![^{}]*})
确保后面没有出现 0+ 次 {
和 }
紧邻当前位置右侧的 }
。 注意这种方法意味着字符串包含均衡数量的左大括号/右大括号。
关于java - 对字符串执行替换但忽略某些模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59301911/