¿Cuál es el equivalente de Regex-replace-with-function-evaluation en Java 7?

Estoy buscando una manera muy simple de obtener el equivalente de algo así como el siguiente código JavaScript. Es decir, para cada coincidencia me gustaría llamar a una determinada función de transformación y utilizar el resultado como valor de reposición.

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" 

Solo … en Java. Y, preferiblemente como un “único método” o “plantilla” que se puede reutilizar.

    Su respuesta está en la documentación de Matcher # appendReplacement . Simplemente ponga su llamada de función en el ciclo while.

    [El método appendReplacement] está destinado a ser utilizado en un bucle junto con los métodos appendTail y find. El siguiente código, por ejemplo, escribe un perro con dos perros en el patio para el flujo de salida estándar:

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

    Al permitir Java 8 puede usar Lambda-Expressions, para tener un JavaScript como replace:

     String result = StringReplacer.replace("Hello World!", Pattern.compile("\\S+"), (Matcher m) -> { return "" + 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, StringReplacerCallback callback) { StringBuffer resultString = new StringBuffer(); Matcher regexMatcher = regex.matcher(input); while (regexMatcher.find()) { regexMatcher.appendReplacement(resultString, callback.replace(regexMatcher)); } regexMatcher.appendTail(resultString); return resultString.toString(); } } 

    StringReplacerCallback.java:

     import java.util.regex.Matcher; public interface StringReplacerCallback { public String replace(Matcher match); } 

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

    No estoy seguro de cuáles son sus requisitos precisos, pero algo así podría funcionar:

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

    Por supuesto, hay otras formas de escribir eso, y ajustes que se pueden hacer dependiendo de los requisitos (por ejemplo, usar un delimitador más preciso que un espacio).

    Para una implementación precisa de su fragmento, podría usar, por ejemplo, StreamTokenizer con un StringReader y algunas envolturas para analizar los delimitadores e insertarlos entre los conteos.