29

我正在寻找一种非常简单的方法来获得类似于以下 JavaScript 代码的内容。也就是说,对于每个匹配,我想调用某个转换函数并将结果用作替换值。

var res = "Hello World!".replace(/\S+/, function (word) {
    // Since this function represents a transformation,
    // replacing literal strings (as with replaceAll) are not a viable solution.
    return "" + word.length;
})
// res => "5 6"

只有 .. 在 Java 中。并且,最好作为可以重复使用的“单一方法”或“模板”。

4

4 回答 4

29

您的答案在Matcher#appendReplacement文档中。只需将您的函数调用放在 while 循环中即可。

[appendReplacement 方法] 旨在与 appendTail 和 find 方法一起在循环中使用。例如,以下代码将院子里的一只狗两只狗写入标准输出流:

Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat two cats in the yard");
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, "dog");
}
m.appendTail(sb);
System.out.println(sb.toString());
于 2013-11-02T01:07:10.043 回答
16

当允许 Java 8 时,您可以使用 Lambda-Expressions 来替换 JavaScript:

String result = StringReplacer.replace("Hello World!", Pattern.compile("\\S+"), m -> ("" + m.group().length()));

StringReplacer.java:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringReplacer {
    public static String replace(String input, Pattern regex, Function<Matcher, String> callback) {
        StringBuffer resultString = new StringBuffer();
        Matcher regexMatcher = regex.matcher(input);
        while (regexMatcher.find()) {
            regexMatcher.appendReplacement(resultString, callback.apply(regexMatcher));
        }
        regexMatcher.appendTail(resultString);

        return resultString.toString();
    }
}

来源: http: //www.whitebyte.info/programming/string-replace-with-callback-in-java-like-in-javascript

于 2014-12-08T13:51:20.633 回答
15

从 Java 9 开始Matcher.replaceAll

Pattern.compile("\\S+").matcher("Hello World!")
        .replaceAll(mr -> "" + mr.group().length());

自由命名的参数mr是 a ,具有类似orMatchResult的访问方法。mr.group(1)mr.end() - mr.start()

于 2019-09-10T08:23:46.893 回答
-1

不确定您的确切要求是什么,但这样的事情可能会起作用:

String res = "";
for (String piece : "hello world".split(" "))
  res += Integer.toString(piece.length()) + " ";

当然还有其他的写法,并且可以根据要求进行调整(例如,使用比空格更准确的分隔符)。

对于您的代码片段的精确实现,您可以使用例如StreamTokenizeraStringReader和一些包装器来解析分隔符并将它们插入计数之间。

于 2013-11-02T01:09:48.087 回答