J'essaie de comprendre ce bloc de code. Dans le premier, que recherchons-nous dans l'expression?
D'après ce que je comprends, il s'agit de n'importe quel caractère (0 fois ou plus *) suivi d'un nombre compris entre 0 et 9 (une ou plusieurs fois +), suivi d'un caractère quelconque (0 ou plus *).
Lorsque ceci est exécuté, le résultat est:
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
Quelqu'un pourrait-il s'il vous plaît passer par là avec moi?
Quel est l'avantage d'utiliser des groupes de capture?
import Java.util.regex.Matcher;
import Java.util.regex.Pattern;
public class RegexTut3 {
public static void main(String args[]) {
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
} else {
System.out.println("NO MATCH");
}
}
}
Le problème que vous rencontrez concerne le type de quantificateur. Vous utilisez un quantificateur glouton dans votre premier groupe (index 1 - L'indice 0 représente l'ensemble Pattern
), ce qui signifie qu'il correspondra autant que possible (et comme il s'agit de n'importe quel caractère , il correspondra autant de caractères qu'il y en a pour remplir la condition des groupes suivants).
En bref, votre premier groupe .*
correspond à quoi que ce soit tant que le groupe suivant \\d+
peut correspondre à quelque chose (dans ce cas, le dernier chiffre).
Selon le troisième groupe, il correspondra à tout ce qui se trouve après le dernier chiffre.
Si vous le changez en un quantificateur réticent de votre 1er groupe, vous obtiendrez le résultat que vous attendez, à savoir le 3000 partie.
Notez le point d'interrogation dans le 1er groupe.
String line = "This order was placed for QT3000! OK?";
Pattern pattern = Pattern.compile("(.*?)(\\d+)(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
System.out.println("group 1: " + matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
Sortie:
group 1: This order was placed for QT
group 2: 3000
group 3: ! OK?
Plus d'informations sur Java Pattern
ici .
Enfin, les groupes de capture sont délimités par des crochets et constituent un moyen très utile d’utiliser des références arrière (entre autres), une fois que votre Pattern
correspond à l’entrée.
Dans Java 6, les groupes ne peuvent être référencés que par leur ordre (attention aux groupes imbriqués et à la subtilité de l'ordre).
Dans Java 7, c'est beaucoup plus facile, car vous pouvez utiliser des groupes nommés.
C'est totalement OK.
m.group(0)
) capture toujours la totalité de la zone couverte par votre expression régulière . Dans ce cas, c'est toute la chaîne.(.*)(\\d+)
(la première partie de votre regex) couvre le ...QT300
int du premier groupe et le 0
du second.(.*)
en (.*?)
.Pour plus d'informations sur les gourmands vs les paresseux, vérifiez ce site.
De la doc:
Capturing groups</a> are indexed from left
* to right, starting at one. Group zero denotes the entire pattern, so
* the expression m.group(0) is equivalent to m.group().
Donc, le groupe de capture 0 envoie toute la ligne.
Votre compréhension est correcte. Cependant, si nous traversons:
(.*)
avalera toute la chaîne;(\\d+)
soit satistifed (c'est pourquoi 0
est capturé et non 3000
);(.*)
capturera le reste.Je ne suis toutefois pas certain de l'intention initiale de l'auteur.