2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Dans les expressions régulières ? Il peut représenter une quantité, 0 ou 1 fois, équivalente à {0, 1}, ou il peut être utilisé comme caractère spécial pour représenter d'autres significations.
? suivi d'autres qualificatifs de quantité indique une correspondance non gourmande, c'est-à-dire correspondant à la chaîne la plus courte possible recherchée.
Regardons un exemple :
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("a.*?");
- Matcher matcher = pattern.matcher("abcabc");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- }
- }
Sortie après exécution : abcabc
N'est-ce pas le match le plus court ? Pourquoi a-t-il échoué ?
Cela implique en fait les règles du matching non gourmand :Pour une correspondance non gourmande, le chemin le plus court est mis en correspondance avant la règle suivante. S'il n'y a pas de règle suivante, il est traité comme une correspondance gourmande.
C'est-à-dire que si seul "a.*?" apparaît, il sera toujours traité selon une correspondance gourmande.
Voyons l'utilisation correcte :
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("(a.*?)(.*)");
- Matcher matcher = pattern.matcher("afcafc");
- if (matcher.matches()) {
- System.out.println(matcher.group(0));
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2));
- }
- }
Sortie après exécution :
- afcafc
- a
- fcafc
Comme vous pouvez le voir, le premier groupe de capture capture la chaîne la plus courte « a » et le deuxième groupe de capture capture « fcafc ».
Examinons les deux autres situations :
Lorsqu'il est utilisé dans un groupe de capture, ? : est placé avant l'expression régulière pour indiquer la correspondance mais pas la capture, c'est-à-dire que ce groupe de valeurs correspondantes ne peut pas être obtenu via la méthode de groupe.
Voyons un exemple
- @Test
- public void test0() {
- Pattern pattern = Pattern.compile("\d{4}-(?:[a-z]+)");
- Matcher matcher = pattern.matcher("3214-opo");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1)); // 报错
- }
- }
Une erreur sera signalée lors de la capture via group(1), c'est-à-dire qu'elle peut être mise en correspondance mais ne peut pas être capturée. Si ?: est supprimé, il peut être capturé normalement via group(1).
(?s) active le mode ligne unique sur le côté droit, ce qui fait que . correspond à n'importe quel caractère, y compris le caractère de nouvelle ligne n.
Regardons un exemple :
- private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)";
-
-
- /**
- * 从输出结果可知,匹配到了换行符 'n'
- */
- @Test
- public void test4() {
- Pattern pattern = Pattern.compile(DEFAULT_VARIABLE_PATTERN);
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2)); // (?s) 不能作为捕获组,报错
- }
- }
Lors de la capture, (?s) ne peut pas être capturé en tant que groupe de capture, donc "((?s).*)" peut capturer le groupe (1) au maximum, et une erreur sera signalée lors de la capture du groupe (2).
- @Test
- public void test5() {
- Pattern pattern = Pattern.compile("(.*)");
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- }
- }
Après avoir supprimé les (?s), essayez de faire correspondre "abcnsdf". Comme il y a un caractère de nouvelle ligne, la correspondance ne peut pas être terminée, donc rien ne sera affiché.