2015-11-05 19 views
5

Sınırsız bölme tüm dizgiyi böler, ancak bir sınır belirlerseniz bu sınırı sola böler. Aynı şeyi nasıl doğru yapabilirim?Bir dizgiyi java'da sağdaki bir sınırla nasıl bölerim?

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

Ben

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

EDIT isteyeyim: Ben

isteyeyim sadece ben daha karmaşık bir örneği eklemek splited ama çok ters gibi çalışır genel çözüm istiyor

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

bunu ters çevirin :) – blank

+0

Blank: D Komik bir çözüm var ama orada çok fazla hesaplama var ve eğer ayırıcı tek bir karakter değilse de onu ters çevirmeliydim ... – aalku

+0

çok fazla hesaplama? Bu tür şeyler için bilgisayarlarımız var! ama evet daha karmaşık hale geliyor – blank

cevap

1

böyle bir şey ile denemek:

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 + ".*$)"; 
} 

bölünme düzenli ifade \\. için öyleyse, alacak, bir diğeri tarafından sarılır: \\.(?!.*\\..*$) maç ve son bir oluşumu üzerinde bölünmüş için sınırlayıcı. Bu regex ile string çok kez bölünür, sonuç dizisinin ikinci elemanı Listeye eklenir, sonraki bölüm sonuç dizisinin ilk elemanında yapılır.

Örnek dizginiz için yukarıdaki yöntemin etkisi beklendiği gibidir.

5

İleriye dönük eşleme kullanabilirsiniz:

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

Burada "Sadece bundan sonra başka bir nokta olmayan noktaya bölünmek istiyorum" diyorsunuz.

son N noktalar ile bölmek istiyorsanız

, bu (daha çirkin bir şekilde) bu çözümü genelleme yapabiliriz:

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

N-2 ile 3 değiştirin.

yerine kısa statik yöntem yazardı Ancak: rağmen

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

Sınır 2 ise hoş bir çözüm. Bir parametre olmasına izin veren herhangi bir varyant? Regex dizesinde {2} gibi bir şey dahil etmeyi umursamıyorum. Ve regex bu ayırıcıya özgüdür. Herhangi bir ayırıcıya adapte etmek o kadar kolay değildir. Teşekkür ederim – aalku

+0

Ben sadece 'splitAtLastDot' yaptım ama sadece 2 limit için değil, genel bir çözüm olup olmadığını merak ettim. – aalku

+1

Özyineleme kokusu alıyorum – px5x2

2

o uzun alacağını tersine dedi here's Dize hürmet eder limiti bunu böler küçük programm;

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

Normal ifadeler "->" 'gibi yönlüyse ve bir regex'i her zaman tersine çeviremezseniz bu işe yaramaz. – aalku

+1

Evet, bu daha karmaşık bir ifade üzerinde çalışmayacak, ancak daha basit bir normal ifade için bu çalışmalıdır. Karmaşık bir ifade için çalışmasını sağlamak için normal ifadeyi ters çevirmeniz gerekir. – SomeJavaGuy

İlgili konular