L'idiome typique pour traiter les sous-chaînes qui correspondent à une expression régulière à l'aide de java.regex.Matcher
est:
Pattern pattern = Pattern.compile("(cola)+");
Matcher matcher = pattern.matcher("cola, cola, I love cola.");
while (mather.find()) {
// do something with the current match.
System.err.println(matcher.group());
}
Si vous souhaitez simplement effectuer un traitement en lecture seule pour la partie correspondante, vous devriez pouvoir l'écrire en tant que traitement de flux. Comme ça.
Matcher matcher = pattern.matcher("cola, cola, I love cola.");
matcher.forEach(h -> System.err.println(h.group()); //h est quelque chose qui représente une correspondance (doit être défini)
Il était bon de penser que cela pouvait être réalisé en créant une implémentation de java.util.stream.Stream
qui encapsule Matcher
, mais c'est difficile à implémenter car il y a trop d'interfaces et de méthodes.
https://docs.oracle.com/javase/jp/9/docs/api/java/util/stream/Stream.html
Existe-t-il un moyen simple d'implémenter Stream
?
Matcher
L'article original listait les solutions générales ci-dessous, mais pour Matcher
, vous pouvez obtenir la réponse complète en utilisant Matcher # results ()
de Java 9. La mise en œuvre de cette méthode implémente exactement ce que j'ai écrit ci-dessus.
Pattern pattern = Pattern.compile("(cola)+");
pattern.matcher("cola, cola, I love cola.").results()
.forEach(x -> System.err.println(x.group()));
REMARQUE: Merci à @ saka1029 pour l'avoir signalé. De plus, veuillez vous référer à ce qui suit pour la méthode générale de vouloir itérer autre chose que «Matcher».
À la suite d'un peu de recherche, il a été trouvé que ce qui suit peut être écrit en combinant StreamSupport # stream
et Spliterators # spliteratorUnknownSize
.
Comme vous pouvez le voir, cette méthode peut être appliquée non seulement à Matcher
mais aussi à l'implémentation de java.util.Iterator
.
C'est pourquoi il est si polyvalent que je vais en prendre note.
[Ajout: je comprends que cet exemple seul est plus long et plus compliqué que le code original :-)]
RegExTest.java
import java.util.Iterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
*
*/
public class RegExTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
final Pattern pattern = Pattern.compile("(cola)+");
final Stream<Matcher> s = StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
new Iterator<Matcher>() {
final Matcher matcher = pattern.matcher("cola, cola, I love cola.");
@Override
public boolean hasNext() {
return matcher.find();
}
@Override
public Matcher next() {
return matcher;
}
},
Spliterator.NONNULL | Spliterator.IMMUTABLE),
false);
//Vous pouvez maintenant l'utiliser de la même manière que l'exemple du début!
s.forEach(m -> System.err.println(m.group()));
}
}
java.util.Iterator
@ saka1029 a de nouveau souligné, la méthode Stream # iterate fournie par Java9 de java.util.stream.Stream
. En utilisant api / java / util / stream / Stream.html # iterate (T, java.util.function.Predicate, java.util.function.UnaryOperator)), c'est beau sans implémenter ʻIterator` comme indiqué ci-dessous. J'ai appris que je peux écrire. Merci, @ saka1029. Je suis heureux que Java9 ait fourni cette nouvelle façon d'écrire, car il y aurait eu beaucoup de personnes autres que moi qui auraient souhaité pouvoir l'écrire comme ça.
final Pattern pattern = Pattern.compile("(cola)+");
Stream.iterate(pattern.matcher("cola, cola, I love cola."), m -> m.find(), m -> m)
.forEach(m -> System.out.println(m.group()));
Recommended Posts