Would this replaceAll function be a good addition to the Regex class?

32 views
Skip to first unread message

Colin Bartolome

unread,
Apr 26, 2017, 12:11:50 PM4/26/17
to ceylon-users
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 ("<") "&lt;"
           
case (">") "&gt;"
           
case ("\"") "&quot;"
           
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?

Colin Bartolome

unread,
May 1, 2017, 8:49:28 PM5/1/17
to ceylon-users
Reply all
Reply to author
Forward
0 new messages