仅在由某个字符分隔的文本的某些部分中替换子字符串

时间:2017-04-05 07:14:53

标签: java regex string substring

我需要替换所有出现的子字符串,只要它前面有"]"然后是" [" (先前和后面但不一定在子字符串旁边)。例如:

这是我需要进行替换的字符串:

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

如果要替换的表达式是:info - >改变(可能不止一个单词)

结果应为:

[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

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

2 个答案:

答案 0 :(得分:3)

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

例如,您可以使用拆分执行此操作(假设您的[]均衡,您没有打开两个[[等):

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();

答案 1 :(得分: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匹配,则发生替换,否则匹配的[...]子字符串将插回到结果中。

至于你的原始逻辑,是的,你可以使用&#34;简单&#34; .replaceAll使用(?:\G|(?<=]))([^\]\[]*?)\binfo\b正则表达式(替换为$1change),但我怀疑这是您需要的。