This question already has answers here:
Regex: match only outside parenthesis (so that the text isn't split within parenthesis)?
(2个答案)
4个月前关闭。
我(Regex noob)试图对包含某些模式的字符串执行替换操作。例如
在上面,我试图将所有
为此,我可以做的是在模式上拆分整个字符串,然后执行替换,然后将字符串连接起来。
我想知道正则表达式中是否有更短的方法,以便我可以执行类似
图案可以像
包含任何字符
可以在字符串的开头,中间或结尾
请参见online demo。
在这里,
较旧的Java版本的等效代码:
请参见online Java demo。
您还可以对任何Java版本使用通用的解决方法:
其中
(2个答案)
4个月前关闭。
我(Regex noob)试图对包含某些模式的字符串执行替换操作。例如
AAA-BBB-CCC-{AAA-BBB-AAA-BBB}-CCC-BBB-AAA
在上面,我试图将所有
A
替换为I
,但忽略大括号内的A
。为此,我可以做的是在模式上拆分整个字符串,然后执行替换,然后将字符串连接起来。
我想知道正则表达式中是否有更短的方法,以便我可以执行类似
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
图案可以像
包含任何字符
可以在字符串的开头,中间或结尾
最佳答案
考虑到没有嵌套的花括号,一种解决方案是匹配最接近的{
和}
内的子字符串,并匹配并捕获要替换的模式,然后检查Group 1是否不为null,然后采取相应措施。
在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+次,紧随其后的是当前位置右侧的}
。注意此方法意味着该字符串包含平衡数量的打开/关闭大括号。