2016-04-08 24 views
2

Oluşumun 4'den fazla olmaması durumunda ilk kez atlamak istiyorum. Şimdilik en fazla 5 sayı alt çizgi oluşumu alacağım. A_B, C, D, E, F çıkışlarını üretmem gerekiyor ve aşağıdaki kodu kullandım. Daha iyi bir çözüm istiyorum. Lütfen kontrol et ve beni bilgilendir. Şimdiden teşekkürler.İlk geçişi atla ve dizgeyi Java'ya böl.

String key = "A_B_C_D_E_F"; 
int occurance = StringUtils.countOccurrencesOf(key, "_"); 
System.out.println(occurance); 
String[] keyValues = null; 
if(occurance == 5){ 
    key = key.replaceFirst("_", "-"); 
    keyValues = StringUtils.tokenizeToStringArray(key, "_"); 
    keyValues[0] = replaceOnce(keyValues[0], "-", "_"); 
}else{ 
    keyValues = StringUtils.tokenizeToStringArray(key, "_"); 
} 

for(String keyValue : keyValues){ 
    System.out.println(keyValue); 
} 
+1

Belki de zaten çalışıyorsa Kod İnceleme'ye aittir. Yığın taşmıyor. –

+1

[Bu demo] 'ya bir göz atın (https://ideone.com/2W3PHE). Bunun neden işe yaradığını bilmiyorum. –

+0

Merhaba Wiktor, Mesajınız için teşekkürler.İhtiyacımı tatmin edecek. İşlerinin nasıl olduğunu kontrol edip anlayacağım. – Abdul

cevap

1

Sen bölmek için bu normal ifadeler kullanabilirsiniz:

String s = "A_B_C_D_E_F"; 
String[] list = s.split("(?<=_[A-Z])_"); 

Çıktı:

[A_B, C, D, E, F]

fikirdir Sadece "_[A-Z]" tarafından verilen ve yalnızca ilkini etkin bir şekilde atlayan _ eşleşmesi. Düşündüğünüz dizeleri "_" arasında farklı bir biçim varsa

, uygun normal ifade tarafından [A-Z] değiştirmek zorunda

+0

sadece bir sidenote gibi, tek sorun, ikinci karakterin tanımsız bir boyuta sahip olmasından sonra artık bunun işe yaramayacağıdır. Ancak bu örnek için mükemmel çalışır. – SomeJavaGuy

+0

@KevinEsche Açıkçası, '[AZ]' i, '_' arasında olanı eşleştirmek için değiştirmelisiniz, ama fikir tam olarak aynı olurdu – Maljam

+0

' '' '' '' '' '' '' '' '' '' '' ' Java'ya bir bakış ve çözümünüz de "4'ten fazla mevcutsa atla" şartına uymaz. – Vampire

0

Sen \G ve yerine bölme kullanımı eşleme dayalı bu normal ifadeler kullanabilirsiniz:

String str = "A_B_C_D_E_F"; 
Pattern p = Pattern.compile("(^[^_]*_[^_]+|\\G[^_]+)(?:_|$)"); 
Matcher m = p.matcher(str); 
List<String> resultArr = new ArrayList<>(); 
while (m.find()) { 
    resultArr.add(m.group(1)); 
} 
System.err.println(resultArr); 

\G, önceki eşleşmenin sonunda ya da ilk eşleşme için dizenin başlangıcını konumlandırır.

Çıktı:

[A_B, C, D, E, F] 

RegEx Demo

0

Ben bölünme sonra bunu yapardı.

public void test() { 
    String key = "A_B_C_D_E_F"; 
    String[] parts = key.split("_"); 
    if (parts.length >= 5) { 
     String[] newParts = new String[parts.length - 1]; 
     newParts[0] = parts[0] + "-" + parts[1]; 
     System.arraycopy(parts, 2, newParts, 1, parts.length - 2); 
     parts = newParts; 
    } 
    System.out.println("parts = " + Arrays.toString(parts)); 
} 
2

Eh, nispeten "basit": Ayrıca olarak kullanılabilir daha iyi anlaşılması için yorumlarla

Burada
String str = "A_B_C_D_E_F_G"; 
String[] result = str.split("(?<!^[^_]*)_|_(?=(?:[^_]*_){0,3}[^_]*$)"); 
System.out.println(Arrays.toString(result)); 

bir sürümüdür:

String str = "A_B_C_D_E_F_G"; 
String[] result = str.split("(?x)     # enable embedded comments \n" 
          + "     # first alternative splits on all but the first underscore \n" 
          + "(?<!    # next character should not be preceded by \n" 
          + " ^[^_]*   #  only non-underscores since beginning of input \n" 
          + ")     # so this matches only if there was an underscore before \n" 
          + "_     # underscore \n" 
          + "|     # alternatively split if an underscore is followed by at most three more underscores to match the less than five underscores case \n" 
          + "_     # underscore \n" 
          + "(?=     # preceding character must be followed by \n" 
          + " (?:[^_]*_){0,3} #  at most three groups of non-underscores and an underscore \n" 
          + " [^_]*$   #  only more non-underscores until end of line \n" 
          + ")"); 
System.out.println(Arrays.toString(result)); 
+0

Desteğiniz için teşekkürler – Abdul

+0

Rica ederim. Sadece yanlış bir cevabı kabul ettiğinizi merak ediyorum. – Vampire

0

Java değil rağmen Resmi olarak, * ve + görünümlerini, sınırlayıcı niceleyiciler olarak uygulandıklarından * ve +'u kullanabilirsiniz: , {0,0x7FFFFFFF} ve +, {1,0x7FFFFFFF} (bakınız Regex look-behind without obvious maximum length in Java). Dizeleriniz çok uzun değilse Yani, , sen JAVA demo

ÖNEMLİ AÇIKLAMA Bkz

String key = "A_B_C_D";  // => [A, B, C, D] 
//String key = "A_B_C_D_E_F"; // => [A_B, C, D, E, F] 
String[] res = null; 
if (key.split("_").length > 4) { 
    res = key.split("(?<!^[^_]*)_"); 
} else { 
    res = key.split("_"); 
} 
System.out.println(Arrays.toString(res)); 

kullanabilirsiniz: Bu bir akım Java 8 regex motorun istismar olduğu için, kod bozabilir gelecekte Java'da hata düzeltildiğinde.

+0

Bu, 4'ten daha fazla olduğunda sadece ilk alt çizgiyi görmezden gelme gereksinimini yerine getirmez. Benim versiyonum var. – Vampire

+0

Şimdi bunu onurlandırıyor. –

+0

Yep, şimdi iki bölmeli işlem gerektirmesine rağmen, benimki bir tane ile çalışıyor. :-) – Vampire