I've found this function I wrote to be pretty useful:
"Finds all matches of the given [[expression]] in the given [[input]] and replaces them using the
given [[replacement]] function."
shared String replaceAll(Regex|String expression, String input,
String(String)|String(MatchResult) replacement) {
value output = StringBuilder();
variable value lastEnd = 0;
value matches = (if (is String expression) then regex(expression) else expression)
.findAll(input);
for (match in matches) {
output.append(input.substring(lastEnd, match.start));
if (is String(String) replacement) {
output.append(replacement(match.matched));
} else {
output.append(replacement(match));
}
lastEnd = match.end;
}
output.append(input.substring(lastEnd));
return output.string;
}
In one spot, I use it like this:
String escape(String string) {
function replaceUnsafeCharacter(String string)
=> switch (string)
case ("&") "&"
case ("<") "<"
case (">") ">"
case ("\"") """
else string;
return replaceAll("""[&<>"]""", string, replaceUnsafeCharacter);
}
Basically, it's Regex.replace(), but you can determine the replacement string depending on exactly what matched. Here's another way I used it, to preprocess some of the
ceylon-lang.org Markdown:
function preprocess(Map<String,String> properties, String markdown) {
value regex = """#\{page\.(\w+)\}""";
function replacement(MatchResult match) {
value key = match.groups.first;
if (exists key) {
return properties[key] else match.matched;
} else {
return match.matched;
}
}
return replaceAll(regex, markdown, replacement);
}
(Interestingly, this use of replaceAll doesn't show up when I hit Ctrl-G in Eclipse. I may try to boil that down to a reproducible case and file it.)
Does something like this already exist in the SDK? If not, would this be a good addition to the Regex class?