Il motivo per cui non si ottiene un optional cat
dopo una riluttanza qualificato .+?
è che è sia facoltativo e non ancorato: il motore non è costretto a fare quella partita, perché può legalmente trattare la cat
come "coda" della sequenza .+?
.
Se yo ancorare il gatto alla fine della stringa, cioè utilizzare ^(dog).+?(cat)?$
, si otterrebbe un match, però:
Pattern p = Pattern.compile("^(dog).+?(cat)?$");
for (String s : new String[] {"dog, cat", "dog, dog, cat", "dog, dog, dog"}) {
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group(1)+" "+m.group(2));
}
}
Questo stampa (demo 1)
dog cat
dog cat
dog null
Do capita di sapere come affrontarlo nel caso ci sia qualcosa dopo il gatto?
Si può trattare con esso costruendo un'espressione più complicato che corrisponde nulla, tranne cat
, in questo modo:
^(dog)(?:[^c]|c[^a]|ca[^t])+(cat)?
Ora il cat
potrebbe accadere in qualsiasi punto della stringa, senza un ancoraggio (demo 2).
Grazie. Ti capita di sapere come affrontarlo nel caso in cui ci sia qualcosa dopo il gatto? Ad esempio: 'cane, cane, gatto, blah'. Voglio catturare solo il primo cane e il gatto opzionale (ci può essere al massimo un gatto). – forsajt
piacerebbe vedere questa risposta –