Je me demande pourquoi les résultats de la regex Java pattern.matcher () et pattern.matches () diffèrent lorsque la même expression régulière et la même chaîne sont fournies
String str = "hello+";
Pattern pattern = Pattern.compile("\\+");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println("I found the text " + matcher.group() + " starting at "
+ "index " + matcher.start() + " and ending at index " + matcher.end());
}
System.out.println(Java.util.regex.Pattern.matches("\\+", str));
Le résultat de ce qui précède sont:
I found the text + starting at index 5 and ending at index 6
false
J'ai trouvé que l'utilisation d'une expression pour faire correspondre la chaîne complète fonctionne bien dans le cas de matches(".*\\+")
.
pattern.matcher(String s)
renvoie une Matcher
qui peut rechercher des modèles dans la chaîne s
. pattern.matches(String str)
teste si la chaîne entière (str
) correspond au modèle.
En bref (juste pour rappeler la différence):
pattern.matcher
- vérifie si la chaîne contient-un motifpattern.matches
- teste si la chaîne is-a patternMatcher.find()
tente de trouver la sous-séquence suivante de la séquence d'entrée correspondant au motif.
Pattern.matches(String regex, CharSequence input)
compile l'expression rationnelle en une Matcher
et retourne Matcher.matches()
.
Matcher.matches
tente de faire correspondre le entier région (chaîne) avec le motif (Regex).
Donc, dans votre cas, la Pattern.matches("\\+", str)
renvoie un faux puisque str.equals("+")
est faux.
Depuis le Javadoc, voyez si, et seulement si, toute la région section
/**
* Attempts to match the entire region against the pattern.
*
* <p> If the match succeeds then more information can be obtained via the
* <tt>start</tt>, <tt>end</tt>, and <tt>group</tt> methods. </p>
*
* @return <tt>true</tt> if, and only if, <b>the entire region</b> sequence
* matches this matcher's pattern
*/
public boolean matches() {
return match(from, ENDANCHOR);
}
Donc, si votre chaîne était juste "+", vous obtiendrez un résultat réel.
match tente de faire correspondre l'expression à la chaîne entière. En d'autres termes, il vérifie si la chaîne entière est un motif ou non . Le pense conceptuellement comme ceci, il ajoute implicitement un ^ au début et un $ à la fin de votre modèle.
Pour String, str = "hello +", si vous souhaitez que matches () renvoie true, vous devez utiliser un modèle du type ".\+. ".
J'espère que cela répond à votre question.
Le code équivalent à Java.util.regex.Pattern.matches("\\+", str)
serait:
Pattern.compile("\\+").matcher(str).matches();
la méthode find
trouvera la première occurrence du motif dans la chaîne.
Je pense que votre question devrait vraiment être "Quand devrais-je utiliser la méthode Pattern.matches()
?", Et la réponse est "Jamais". Vous attendiez-vous à ce qu'il retourne un tableau des sous-chaînes correspondantes, comme le font les méthodes Matches
de .NET? C'est une attente parfaitement raisonnable, mais non, Java n'a rien de tel.
Si vous voulez juste faire une correspondance rapide, ornez la regex avec .*
à chaque extrémité et utilisez la méthode matches()
de la chaîne:
System.out.println(str.matches(".*\\+.*"));
Si vous souhaitez extraire plusieurs correspondances ou accéder aux informations relatives à une correspondance ultérieurement, créez une instance de Matcher et utilisez les méthodes its , comme vous l'avez fait dans votre question. Pattern.matches()
n'est rien qu'une opportunité gâchée.
Matcher matcher = pattern.matcher(text);
Dans ce cas, une instance d'objet matcher sera renvoyée. Elle effectuera des opérations de correspondance sur le texte saisi en interprétant le modèle. Ensuite, nous pouvons utiliser, matcher.find()
pour correspondre à no. des motifs du texte d'entrée.
(Java.util.regex.Pattern.matches("\\+", str))
Ici, l’objet Matcher sera créé implicitement et un booléen sera renvoyé, ce qui fera correspondre tout le texte au motif. Cela fonctionnera comme la fonction str.matches(regex)
dans String.
Pattern.matches teste toute la chaîne. Dans votre cas, vous devriez utiliser:
System.out.println(Java.util.regex.Pattern.matches(".*\\+", str));
Ce qui signifie n'importe quelle chaîne et un symbole +