The following (Java) implementation is part of the GDK:
/**
* Replaces all occurrences of a captured group by the result of a closure on that text.
* <p/>
* <p> For examples,
* <pre>
* assert "FOOBAR-FOOBAR-" == "foobar-FooBar-".replaceAll(~"(([fF][oO]{2})[bB]ar)", { Object[] it -> it[0].toUpperCase() })
* <p/>
* Here,
* it[0] is the global string of the matched group
* it[1] is the first string in the matched group
* it[2] is the second string in the matched group
* <p/>
* <p/>
* assert "FOO-FOO-" == "foobar-FooBar-".replaceAll("(([fF][oO]{2})[bB]ar)", { x, y, z -> z.toUpperCase() })
* <p/>
* Here,
* x is the global string of the matched group
* y is the first string in the matched group
* z is the second string in the matched group
* </pre>
* <p>Note that unlike String.replaceAll(String regex, String replacement), where the replacement string
* treats '$' and '\' specially (for group substitution), the result of the closure is converted to a string
* and that value is used literally for the replacement.</p>
*
* @param self a String
* @param pattern the capturing regex Pattern
* @param closure the closure to apply on each captured group
* @return a String with replaced content
* @since 1.6.8
* @see java.util.regex.Matcher#quoteReplacement(java.lang.String)
*/
public static String replaceAll(final String self, final Pattern pattern, final Closure closure) {
final Matcher matcher = pattern.matcher(self);
if (matcher.find()) {
final StringBuffer sb = new StringBuffer(self.length() + 16);
do {
int count = matcher.groupCount();
List<String> groups = new ArrayList<String>();
for (int i = 0; i <= count; i++) {
groups.add(matcher.group(i));
}
final String replacement = InvokerHelper.toString(closure.call(groups.toArray()));
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
} while (matcher.find());
matcher.appendTail(sb);
return sb.toString();
} else {
return self;
}
}
Are there any similar implementations out there for Javascript? If not, is it feasible to attempt an implementation oneself; how might one go about it?
I hope I’m understanding your question properly, but reading the comments in your example, the sample use cases can be satisfied by the
replacemethod of the js String object.replacecan take a function as its replacement argument: