【问题标题】:Replace regex occurrences替换正则表达式
【发布时间】:2015-02-09 13:40:58
【问题描述】:

我有一个输入字符串:

"hello [you], this is [me]"

我有一个将字符串映射到字符串的函数(为简单起见硬编码):

public String map(final String input) {
    if ("you".equals(input)) {
        return "SO";
    } else if ("me".equals(input)) {
        return "Kate";
    }
    ...
}

将每个出现的[(.*)?] 替换为其各自的映射(通过调用map 函数给出)最方便的方法是什么?

如果我是正确的,你不能在这里使用String.replaceAll(),因为我们事先不知道替换。

【问题讨论】:

  • 你应该使用java.util.Map<String, String>而不是这个函数。

标签: java regex replace


【解决方案1】:

首先,你的表达是贪婪的。匹配方括号中的标记的正确表达式是\[([^\]]*)\](Java 需要将反斜杠加倍),因为它避免越过右方括号*。我添加了一个捕获组,以group(1) 的形式访问方括号内的内容。

这是一种满足您需要的方法:

Pattern p = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = p.matcher(input);
StringBuffer bufStr = new StringBuffer();
boolean flag = false;
while ((flag = m.find())) {
    String toReplace = m.group(1);
    m.appendReplacement(bufStr, map(toReplace));
}
m.appendTail(bufStr);
String result = bufStr.toString();

Demo.

*你也可以使用[.*?],但是这种不情愿的表达可能会导致回溯。

【讨论】:

  • 你的意思是Pattern.compile("\\[[^\\]*]\\]");,否则你的模式会马赫"hello [you"
  • @ericbn 谢谢!我在进行演示时发现了该错误,因此现在已修复。
  • 谢谢。我不太了解 appendReplacement 函数。现在我知道了!
【解决方案2】:

你可以这样做:

String line = "hello [you], this is [me]";

Pattern p = Pattern.compile("\\[(.*?)\\]");
Matcher m = p.matcher(line);

while (m.find()) {
    // m.group(1) contains the text inside [] 
    // line.replace(m.group(1), yourMap.get(m.group(1)));
    // use StringBuilder to build the new string
}

【讨论】:

  • 谢谢。这并不能真正回答完整的问题。一旦发现一个事件(m.group(1)),我如何在原始输入中通过它的映射替换它?
  • 字符串是不可变的 :) line.replace 不会影响行。
  • 通过调用replace,你不是第二次扫描输入字符串吗?
  • @KateDeens 为什么会有问题?
  • 搜索某些东西(使用数学),找到它,然后再次搜索(使用替换功能)似乎很奇怪。
猜你喜欢
  • 1970-01-01
  • 2019-01-24
  • 2015-01-24
  • 1970-01-01
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
相关资源
最近更新 更多