【问题标题】:Replace While Pattern is Found找到模式时替换
【发布时间】:2012-12-16 14:37:29
【问题描述】:

我正在尝试遍历字符串并替换正则表达式匹配字符串的所有实例。出于某种原因,当我使用if 时,它将起作用并仅替换正则表达式匹配的一个字符串实例。当我将 if 更改为 while 时,它会对其自身进行一些奇怪的替换,并在第一个正则表达式匹配的字符串上弄得一团糟,甚至没有触及其他字符串......

        pattern = Pattern.compile(regex);
        matcher = pattern.matcher(docToProcess);
        while (matcher.find()) {
            start = matcher.start();
            end = matcher.end();
            match = docToProcess.substring(start, end);
            stringBuilder.replace(start, end, createRef(match));
            docToProcess = stringBuilder.toString();
        }

【问题讨论】:

  • 您是否尝试过通过在循环中添加一些系统输出来进行调试?另请注意,docToProcess = stringBuilder.toString(); 不会更改匹配器看到的字符串。
  • 如何让它改变匹配器看到的字符串?因为这实际上是问题所在......我不知道如何更新它/刷新它/更改为当前实例
  • 你不能。但是您可以创建一个新的匹配器并将其分配给您现有的局部变量:matcher = pattern.matcher(docToProcess);
  • String newString = oldString.replaceAll(regex,replacement) 不是你想做的吗?
  • @Pshemo 我不这么认为,因为他的替换是由createRef() 动态创建的。由于我们不知道正则表达式,我们不能确定匹配总是相等的。

标签: java regex replace find


【解决方案1】:

除了系统输出之外,我只添加了最后一个作业。看看有没有帮助:

// your snippet:    
pattern = Pattern.compile(regex);
matcher = pattern.matcher(docToProcess);
while (matcher.find()) {
    start = matcher.start();
    end = matcher.end();
    match = docToProcess.substring(start, end);
    String rep = createRef(match);
    stringBuilder.replace(start, end, rep);
    docToProcess = stringBuilder.toString();
    // my addition:
    System.out.println("Found:         '" + matcher.group() + "'");
    System.out.println("Replacing with: '" + rep + "'");
    System.out.println(" --> " + docToProcess);
    matcher = pattern.matcher(docToProcess);
}

【讨论】:

  • 太棒了。我已经为此苦苦挣扎了将近一个星期,我只需要添加一行。分析瘫痪...非常感谢!
【解决方案2】:

不确定你到底遇到了什么问题,但也许这个例子会有所帮助:

我想更改以下句子中的名称:

  • 杰克 -> 艾伯特
  • 阿尔伯特 -> 保罗
  • 保罗 -> 杰克

我们可以在 Matcher 类中的 appendReplacementappendTail 方法的帮助下做到这一点

//this method can use Map<String,String>, or maybe even be replaced with Map.get(key)
static String getReplacement(String name) { 
    if ("Jack".equals(name))
        return "Albert";
    else if ("Albert".equals(name))
        return "Paul";
    else
        return "Jack";
}

public static void main(String[] args) {

    String sentence = "Jack and Albert are goint to see Paul. Jack is tall, " +
            "Albert small and Paul is not in home.";

    Matcher m = Pattern.compile("Jack|Albert|Paul").matcher(sentence);

    StringBuffer sb = new StringBuffer();

    while (m.find()) {
        m.appendReplacement(sb, getReplacement(m.group()));
    }
    m.appendTail(sb);

    System.out.println(sb);
}

输出:

Albert and Paul are goint to see Jack. Albert is tall, Paul small and Jack is not in home.

【讨论】:

    【解决方案3】:

    如果 createRef(match) 返回一个与 (end - start) 长度不同的字符串,那么您在 docToProcess.substring(start, end) 中使用的索引可能会重叠。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-30
      • 2021-11-17
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多