package com.googlecode.totallylazy.regex; import com.googlecode.totallylazy.functions.Function1; import com.googlecode.totallylazy.Sequence; import com.googlecode.totallylazy.iterators.GroupIterator; import java.util.Iterator; import java.util.regex.MatchResult; import java.util.regex.Pattern; import static com.googlecode.totallylazy.functions.Callables.returnArgument; import static com.googlecode.totallylazy.Callers.call; public class Matches extends Sequence<MatchResult> { private final Pattern pattern; private final CharSequence text; public Matches(Pattern pattern, CharSequence text) { this.pattern = pattern; this.text = text; } public Iterator<MatchResult> iterator() { return new MatchIterator(pattern.matcher(text)); } public String replace(Function1<? super MatchResult, ? extends CharSequence> matched) { return replace(returnArgument(CharSequence.class), matched); } public String replace(Function1<? super CharSequence, ? extends CharSequence> notMatched, Function1<? super MatchResult, ? extends CharSequence> matched) { StringBuilder builder = new StringBuilder(); int position = 0; for (MatchResult matchResult : this) { CharSequence before = text.subSequence(position, matchResult.start()); if (before.length() > 0) builder.append(filterNull(call(notMatched, before))); builder.append(filterNull(call(matched, (matchResult)))); position = matchResult.end(); } CharSequence after = text.subSequence(position, text.length()); if (after.length() > 0) builder.append(filterNull(call(notMatched, after))); return builder.toString(); } private static CharSequence filterNull(CharSequence value) { return value == null ? "" : value; } public static class functions { public static Function1<Matches, String> replace(final Function1<? super MatchResult, ? extends CharSequence> constant) { return matchResults -> matchResults.replace(constant); } public static Function1<MatchResult, Sequence<String>> groups = matchResult -> new Sequence<String>() { @Override public Iterator<String> iterator() { return new GroupIterator(matchResult); } }; } }