Java8 でも使えるように書いてみた。。
昨日の、 正規表現マッチのストリーム処理を考察 - Oboe吹きプログラマの黙示録
に続いて、思いついたので、まとめてみた。
import java.util.Iterator; import java.util.Spliterator; import java.util.Spliterators; import java.util.Spliterators.AbstractSpliterator; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; /** * RegExpress.java */ public final class RegExpress{ private RegExpress(){ } public static Stream<String> matchToStream(String regex, CharSequence input){ Matcher m = Pattern.compile(regex).matcher(input); return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator<String>(){ @Override public boolean hasNext(){ return m.find(); } @Override public String next(){ return m.group(); } }, Spliterator.ORDERED), false); } public static Stream<MatchResult> findMatches(String regex, CharSequence input){ Matcher matcher = Pattern.compile(regex).matcher(input); Spliterator<MatchResult> spliterator = new AbstractSpliterator<MatchResult>(Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.NONNULL){ @Override public boolean tryAdvance(Consumer<? super MatchResult> action){ if (!matcher.find()) return false; action.accept(matcher.toMatchResult()); return true; } }; return StreamSupport.stream(spliterator, false); } public static void results(String regex, String input, Consumer<String> c){ Matcher m = Pattern.compile(regex).matcher(input); while(m.find()){ c.accept(m.group()); } } public static void resultMatch(String regex, String input, Consumer<MatchResult> c){ Matcher m = Pattern.compile(regex).matcher(input); while(m.find()){ c.accept(m.toMatchResult()); } } public static void resultMatch(String regex, String input, BiConsumer<MatchResult, Integer> c){ Matcher m = Pattern.compile(regex).matcher(input); AtomicInteger i = new AtomicInteger(0); while(m.find()){ c.accept(m.toMatchResult(), i.getAndIncrement()); } } public static String replace(String regex, String string, BiFunction<String, Integer, String> f){ Matcher m = Pattern.compile(regex).matcher(string); AtomicInteger i = new AtomicInteger(0); AtomicInteger x = new AtomicInteger(0); return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator<String>(){ @Override public boolean hasNext(){ return m.find(); } @Override public String next(){ return string.substring(i.getAndSet(m.end()), m.start()) + f.apply(m.group(), x.getAndIncrement()); } }, Spliterator.ORDERED), false).collect(Collectors.joining()) + string.substring(i.get()); } }
使用例
RegExpress.matchToStream("[0-9]+", string).forEach(e->System.out.println("["+e+"]")); RegExpress.findMatches("[0-9]+", string) .forEach(m->System.out.println("["+m.group()+"] start="+m.start()+" end="+m.end())); RegExpress.resultMatch("[0-9]+", string, m->{ System.out.println("["+m.group()+"] start="+m.start()+" end="+m.end()); }); RegExpress.resultMatch("[0-9]+", string, (m, i)->{ System.out.println(i+":["+m.group()+"] start="+m.start()+" end="+m.end()); }); String res = RegExpress.replace("[0-9]+", string, (e, i)->"{"+i+":"+e+"}");