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?
MatcherL'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