2013-07-31 18 views
17

Nel codice seguente:Java regex - sovrapposizione partite

public static void main(String[] args) { 
    List<String> allMatches = new ArrayList<String>(); 
    Matcher m = Pattern.compile("\\d+\\D+\\d+").matcher("2abc3abc4abc5"); 
    while (m.find()) { 
     allMatches.add(m.group()); 
    } 

    String[] res = allMatches.toArray(new String[0]); 
    System.out.println(Arrays.toString(res)); 
} 

Il risultato è:

[2abc3, 4abc5] 

mi piacerebbe che fosse

[2abc3, 3abc4, 4abc5] 

Come può essere raggiunto?

+0

Avresti bisogno di cercare a partire da ogni indice; usa il metodo find (int startingIndex) e cerca a partire da ogni posizione del personaggio. Naturalmente, è probabile che tu trovi troppe corrispondenze ... Supponendo che tu voglia iniziare a ogni numero, potresti provare a combinare un'iterazione su Matcher.find (String.indexOf (cifre, indice)) per tutti gli indici corrispondenti. – user1676075

+0

Suppongo che, se si tratta di cifre singole, è possibile eseguire il backup dalla posizione di partenza della partita e trovare da lì per la prossima partita. – user1676075

+1

Per l'input '" 12abc13abc14abc15 "', vuoi '[12abc13, 2abc13, 13abc14, 3abc14, 14abc15, 4abc15]' o '[12abc13, 13abc14, 14abc15]'? – johnchen902

risposta

15

fare il tentativo matcher per iniziare il suo ciclo successivo da quest'ultimo \d+.

Matcher m = Pattern.compile("\\d+\\D+(\\d+)").matcher("2abc3abc4abc5"); 
if (m.find()) { 
    do { 
     allMatches.add(m.group()); 
    } while (m.find(m.start(1))); 
} 
+0

Per i primi due up-voter: la versione ordinaria contiene un bug che, se non corrisponde nulla, verrà lanciato un 'IllegalStateException'. – johnchen902

+0

+1 per bella improvvisazione. – anubhava

13

Non sono sicuro se questo è possibile in Java, ma in PCRE si potrebbe effettuare le seguenti operazioni:
(?=(\d+\D+\d+)).

Spiegazione
La tecnica è quella di utilizzare un gruppo di corrispondenza in un lookahead, e poi " mangia "un personaggio per andare avanti.

  • (?=: inizio lookahead positivo
    • (: inizio corrispondente gruppo 1
      • \d+: corrispondere una cifra una o più volte
      • \D+: abbinare un carattere non numerico una o più volte
      • \d+: corrisponde a una cifra una o più volte
    • ): fine del gruppo 1
  • ): fine lookahead
  • .: mai soddisfatta, questo è quello di "andare avanti".

Online demo


Grazie ad Casimir et Hippolyte sembra davvero di lavorare in Java. Hai solo bisogno di aggiungere barre retroverse e visualizzare il primo gruppo di acquisizione: (?=(\\d+\\D+\\d+)).. provata su www.regexplanet.com:

enter image description here

+1

Funziona anche in java. –

+2

Fornisce risultati errati. – anubhava

+2

Non funziona in java. – JDiPierro

1

La soluzione sopra descritta di HamZa funziona perfettamente in Java. Se si vuole trovare un modello specifico in un testo tutto quello che dovete fare è:

String regex = "\d+\D+\d+"; 

String updatedRegex = "(?=(" + regex + "))."; 

Qualora il regex è il modello che si sta cercando e di essere sovrapposte è necessario circondare con (?=(" at the start and ")). alla fine.