2017-04-05 71 views
1

我需要替换所有出现的子字符,只要前面有“]”,后面跟着“[”(前后并且不一定紧挨着子字符串)。例如:只在部分字符分隔的文本的某些部分替换子字符

这将是我需要做替换字符串:

[style and tags info] valid text info [more style info] more info here[styles] 

如果更换表述是:信息 - >更改(可能不止一个单词)

结果应该是:

[style and tags info] valid text change [more style info] more change here [styles] 

我的想法是使用正则表达式来隔离我必须要改变,然后让一起的replaceAll呼叫更换的话。

但我已经尝试了几个正则表达式来隔离搜索表达式而没有成功。主要是因为我需要类似

(?<=.*) 

这是,在我正在寻找的单词前面有任意数量的字符。这不被Java正则表达式支持(也不支持我知道的任何其他正则表达式的实现)。

我发现这个解决方案,MATLAB写的,但似乎很难在Java中复制:

Matlab regex - replace substring ONLY within angled brackets

有没有更简单的方法呢?一些正则表达式我没有考虑过?

+0

为什么不在''[']之外替换'change'?我的意思是,如果'info'在第一个'[...]'之前,它不应该被替换吗? –

回答

1

它似乎更合适匹配,并跳过以[开头的子字符串,然后除[]以外的字符数不得超过],并在所有其他上下文中将info替换为change。为了这个目的,你可以使用Matcher#appendReplacement()方法:

String s = "[style and tags info] valid text info [more style info] more info here[styles]"; 
StringBuffer result = new StringBuffer(); 
Matcher m = Pattern.compile("\\[[^\\]\\[]+]|\\b(info)\\b").matcher(s); 
while (m.find()) { 
    if (m.group(1) != null) { 
     m.appendReplacement(result, "change"); 
    } 
    else { 
     m.appendReplacement(result, m.group()); 
    } 
} 
m.appendTail(result); 
System.out.println(result.toString()); 
// => [style and tags info] valid text change [more style info] more change here[styles] 

Java demo

\[[^\]\[]+]|\b(info)\b正则表达式的[...]子与\[[^\]\[]+]选择分支和\b(info)\b分支(第1组)匹配捕捉整个单词info。如果组1匹配,则进行替换,否则匹配的[...]子串将被插回到结果中。

至于你逻辑,是的,你可以用一个“简单” .replaceAll(?:\G|(?<=]))([^\]\[]*?)\binfo\b正则表达式(与$1change更换),但我怀疑这是你所需要的。

+1

完美无瑕!即使在文本的某个位置使用了不匹配的括号。非常感谢 –

3

我想说这里最简单的方法是将字符串拆分为(括号外的部分)和(括号内的部分),然后仅将替换应用于(括号内的部分)。

例如,你可以做到这一点采用分体式(这里假设你的[] s为均衡的,你不打开两个[[等):

String[] parts = str.split("[\[\]]"); 
StringBuilder sb = new StringBuilder(str.length()); 
for (int i = 0; i < parts.length; i++) { 
    if (i % 2 == 0) { 
    // This bit was outside []. 
    sb.append(parts[i]); 
    } else { 
    // This bit was inside [], so apply the replacement 
    // (and re-append the delimiters). 
    sb.append("["); 
    sb.append(parts[i].replace("info", "change")); 
    sb.append("]"); 
    } 
} 
String newStr = sb.toString();