Wie erstelle ich einen Stream von regex-matches?

Ich versuche zu analysieren standard-input und extrahieren Sie alle Strings, die übereinstimmungen mit einem bestimmten Muster, zählen Sie die Anzahl der vorkommen jedes Spiel, und drucken Sie die Ergebnisse alphabetisch. Dieses problem scheint, wie ein gutes match für die Streams-API, aber ich kann nicht finden, einen prägnanten Weg, um erstellen Sie einen stream der Spiele von einem Matcher.

Ich arbeitete um dieses problem durch die Implementierung eines iterator über die Spiele und wickeln Sie es in ein Stream, aber das Ergebnis ist nicht sehr gut lesbar ist. Wie kann ich einen stream erstellen, der der regex entspricht, ohne die Einführung zusätzlicher Klassen?

public class PatternCounter
{
    static private class MatcherIterator implements Iterator<String> {
        private final Matcher matcher;
        public MatcherIterator(Matcher matcher) {
            this.matcher = matcher;
        }
        public boolean hasNext() {
            return matcher.find();
        }
        public String next() {
            return matcher.group(0);
        }
    }

    static public void main(String[] args) throws Throwable {
        Pattern pattern = Pattern.compile("[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)");

        new TreeMap<String, Long>(new BufferedReader(new InputStreamReader(System.in))
            .lines().map(line -> {
                Matcher matcher = pattern.matcher(line);
                return StreamSupport.stream(
                        Spliterators.spliteratorUnknownSize(new MatcherIterator(matcher), Spliterator.ORDERED), false);
            }).reduce(Stream.empty(), Stream::concat).collect(groupingBy(o -> o, counting()))
        ).forEach((k, v) -> {
            System.out.printf("%s\t%s\n",k,v);
        });
    }
}
InformationsquelleAutor Alfredo Diaz | 2015-01-26
Schreibe einen Kommentar