2015-11-05 24 views
5

Dividi senza limiti dividere l'intera stringa, ma se si imposta un limite si divide fino a quel limite di sinistra. Come posso fare lo stesso con la destra?Come dividere una stringa con un limite che inizia con la destra in java?

"a.b.c".split("[.]", 2); // returns ["a", "b.c"] 

vorrei

"a.b.c".splitRight("[.]", 2); // to return ["a.b", "c"] 

EDIT: io voglio una soluzione generale che funziona proprio come splited ma invertito così aggiungo un esempio più complesso

vorrei

"a(->)b(->)c(->)d".splitRight("\\(->\\)", 3); // to return ["a(->)b", "c", "d"] 
+2

inverso prima :) – blank

+0

@blank: D Soluzione divertente ma c'è troppo lavoro di calcolo lì e se il separatore non è un singolo carattere avrei dovuto invertirlo anch'io ... – aalku

+0

troppo calcolo? abbiamo computer per questo genere di cose! ma sì, diventa più complicato – blank

risposta

1

vorrei provare con qualcosa di simile:

public List<String> splitRight(String string, String regex, int limit) { 
    List<String> result = new ArrayList<String>(); 
    String[] temp = new String[0]; 
    for(int i = 1; i < limit; i++) { 
     if(string.matches(".*"+regex+".*")) { 
      temp = string.split(modifyRegex(regex)); 
      result.add(temp[1]); 
      string = temp[0]; 
     } 
    } 
    if(temp.length>0) { 
     result.add(temp[0]); 
    } 
    Collections.reverse(result); 
    return result; 
} 

public String modifyRegex(String regex){ 
    return regex + "(?!.*" + regex + ".*$)"; 
} 

L'espressione regolare per la spaccatura è avvolto da un altro, così per \\., si otterrà: \\.(?!.*\\..*$), da abbinare e diviso in ultima occorrenza di delimitatore. La stringa viene divisa più volte con questa regex, il secondo elemento dell'array di risultati viene aggiunto a List, la successiva divisione viene eseguita sul primo elemento dell'array di risultati.

L'effetto del metodo precedente per la stringa di esempio è come previsto.

5

È possibile utilizzare la corrispondenza look-ahead:

"a.b.c".split("[.](?=[^.]*$)") 

Qui dici "Voglio dividere solo quel punto che non ha altri punti dopo di esso".

Se si desidera raggruppati per ultimi N punti, si può generalizzare questa soluzione in questo (modo ancora più brutto):

"dfsga.sdgdsb.dsgc.dsgsdfg.dsdg.sdfg.sdf".split("[.](?=([^.]*[.]){0,3}[^.]*$)"); 

Sostituire 3 con N-2.

Tuttavia vorrei scrivere un metodo statico breve invece:

public static String[] splitAtLastDot(String s) { 
    int pos = s.lastIndexOf('.'); 
    if(pos == -1) 
     return new String[] {s}; 
    return new String[] {s.substring(0, pos), s.substring(pos+1)}; 
} 
+0

Bella soluzione se il limite è 2. Qualunque variante per consentire che sia un parametro? Non mi dispiace includere qualcosa come '{2}' nella stringa regex. E la regex è specifica per quel separatore. Non è così facile adattarlo a qualsiasi separatore. Grazie – aalku

+0

Ho fatto proprio questo 'splitAtLastDot', ma mi sono chiesto se esiste una soluzione generale, non solo per il caso limite 2. – aalku

+1

Odore la ricorsione – px5x2

2

Nonostante che hai detto retromarcia sarebbe troppo lungo, ecco un piccolo programma che venera la corda e la divide dal limite;

static String[] leftSplit(String input, String regex, int limit) { 
    String reveresedInput = new StringBuilder(input).reverse().toString(); 
    String[] output = reveresedInput.split(regex, limit); 
    String tempOutput[] = new String[output.length]; 
    for(int i = 0;i<output.length;++i) { 
     tempOutput[tempOutput.length-i-1] = new StringBuilder(output[i]).reverse().toString(); 
    } 
    return tempOutput; 
} 

public static void main(String[] args) { 
    System.out.println(Arrays.toString(leftSplit("a.b.c", "[.]", 2))); 
    System.out.println(Arrays.toString(leftSplit("I want to. Split this. by the. right side", "[.]", 2))); 
} 
+1

Questo non funzionerebbe se la regex è direzionale come '" -> "' e non è sempre possibile invertire una regex. – aalku

+1

Sì, questo non funzionerà su una regex più complessa, ma per una regex più semplice dovrebbe funzionare. Per farlo funzionare per una regex complessa, dovresti invertire la regex. – SomeJavaGuy

Problemi correlati