le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Nelle espressioni regolari,? Può rappresentare una quantità, 0 o 1 volte, equivalente a {0, 1} oppure può essere utilizzato come carattere speciale per rappresentare altri significati.
? seguito da altri qualificatori di quantità indica una corrispondenza non greedy, ovvero una corrispondenza con la stringa più breve possibile cercata.
Diamo un'occhiata a un esempio:
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("a.*?");
- Matcher matcher = pattern.matcher("abcabc");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- }
- }
Output dopo l'esecuzione: abcbc
Non è la partita più breve? Perché ha fallito?
Ciò in realtà coinvolge le regole dell'abbinamento non avido:Per l'abbinamento non greedy, il percorso più breve viene abbinato prima della regola successiva. Se non esiste una regola successiva, viene elaborato come abbinamento greedy.
Vale a dire, se appare solo "a.*?", verrà comunque elaborato secondo la corrispondenza greedy.
Vediamo l’utilizzo corretto:
- @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));
- }
- }
Output dopo l'esecuzione:
- afcafc
- a
- fcafc
Come puoi vedere, il primo gruppo di acquisizione cattura la stringa più breve "a" e il secondo gruppo di acquisizione cattura "fcafc".
Diamo un’occhiata alle altre due situazioni:
Se utilizzato in un gruppo di acquisizione, ?: viene posizionato prima dell'espressione regolare per indicare la corrispondenza ma non l'acquisizione, ovvero questo gruppo di valori corrispondenti non può essere ottenuto tramite il metodo group.
Vediamo un esempio
- @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)); // 报错
- }
- }
Verrà segnalato un errore durante l'acquisizione tramite group(1), ovvero è possibile far corrispondere ma non acquisire. Se ?: viene rimosso, può essere catturato normalmente tramite group(1).
(?s) attiva la modalità a riga singola sul lato destro, facendo corrispondere . a qualsiasi carattere, incluso il carattere di nuova riga n.
Diamo un'occhiata a un esempio:
- 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) 不能作为捕获组,报错
- }
- }
Durante l'acquisizione, (?s) non può essere catturato come gruppo di acquisizione, quindi "((?s).*)" può catturare al massimo il gruppo(1) e verrà segnalato un errore durante l'acquisizione del gruppo(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));
- }
- }
Dopo aver rimosso le (?s), prova a trovare la corrispondenza con "abcnsdf". Poiché è presente un carattere di nuova riga, la corrispondenza non può essere completata, quindi non verrà restituito nulla.