Upgrade Regex with a tester() method?

Peter Levart peter.levart at gmail.com
Tue Jan 22 05:29:34 PST 2013


On 01/22/2013 12:24 PM, Peter Levart wrote:
> On 01/22/2013 09:29 AM, Paul Sandoz wrote:
>> On Jan 21, 2013, at 6:20 PM, Peter Levart <peter.levart at gmail.com> 
>> wrote:
>>> Another possible point lambdafication is an idiom that is frequent 
>>> with using pattern matching - replacement:
>>>
>>> public class Pattern { ...
>>>
>>>     public String replaceAll(String str, Function<String, String> 
>>> replacementFunction) {
>>>         Matcher m = matcher(str);
>>>         StringBuffer sb = new StringBuffer();
>>>         while (m.find()) {
>>>             m.appendReplacement(sb, 
>>> replacementFunction.apply(m.group(1)));
>>>         }
>>>         m.appendTail(sb);
>>>         return sb.toString();
>>>     }
>>>
>>> so one can write:
>>>
>>>         Pattern pattern = Pattern.compile("\\{(.*?)\\}");
>>>         String msg = pattern.replaceAll(
>>>             "User's home is: {user.home}, current dir is: {user.dir}",
>>> System::getProperty
>>> );
>>>
>> Perhaps those function-based methods would be more appropriate on 
>> Matcher as overloads of replaceAll and replaceFirst?
>>
>> Paul.
>
> That's better Paul, yes, since there is already 
> Matcher.replaceAll(String replacement). I would also change the 
> function to take the Matcher instance as the parameter instead of 
> matched group #1 - more flexible:

Or even better, the function parameter should be MatchResult (not 
Matcher that implements this interface) so that user is not tempted to 
produce any side-effects in the function body:

public class Matcher { ...

     public String replaceAll(Function<MatchResult, String> 
replacementFunction) {

Regards, Peter

>
> public class Matcher { ...
>
>     public String replaceAll(Function<Matcher, String> 
> replacementFunction) {
>         reset();
>         boolean result = find();
>         if (result) {
>             StringBuffer sb = new StringBuffer();
>             do {
>                 appendReplacement(sb, replacementFunction.apply(this));
>                 result = find();
>             } while (result);
>             appendTail(sb);
>             return sb.toString();
>         }
>         return text.toString();
>     }
>
> So the above usage becomes:
>
>     Pattern pattern = Pattern.compile("\\{(.*?)\\}");
>
>     String msg = pattern
>         .matcher("User's home is: {user.home}, current dir is: 
> {user.dir}")
>         .replaceAll(m -> System.getProperty(m.group(1)));
>
>
>
> Regards, Peter
>
>>
>>> This method could then also be overloaded on String as a shortcut 
>>> without precompiled Pattern instance:
>>>
>>> public class String {...
>>>
>>>     public String replaceAll(String regex, Function<String, String> 
>>> replacementFunction) {
>>>         return Pattern.compile(regex).replaceAll(this, 
>>> replacementFunction);
>>>     }
>>>
>>> so one could write:
>>>
>>>     String msg = "User's home is: {user.home}, current dir is: 
>>> {user.dir}"
>>>                      .replaceAll("\\{(.*?)\\}", System::getProperty);
>>>
>



More information about the lambda-dev mailing list