【问题标题】:Replace substring only in certain portions of text delimited by some character仅在由某些字符分隔的文本的某些部分中替换子字符串
【发布时间】:2017-08-30 15:53:39
【问题描述】:

我需要替换所有出现的子字符串,前提是它前面是“]”,后面是“[”(前面和后面,但不一定在子字符串旁边)。示例:

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

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

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

结果应该是:

[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

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

【问题讨论】:

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

标签: java regex string substring


【解决方案1】:

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

例如,您可以使用 split 来执行此操作(假设您的 []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();

【讨论】:

    【解决方案2】:

    匹配并跳过以[开头的子字符串,然后有1个或多个除[]之外的字符直到结束],并将info替换为@似乎更合适987654328@ 在所有其他情况下。为此,您可以使用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 组匹配,则进行替换,否则,将匹配的 [...] 子字符串插入回结果中。

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

    【讨论】:

    • 完美运行!即使在文本的某些位置使用不匹配的括号。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 2011-12-31
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    相关资源
    最近更新 更多