2016-04-08 9 views
2

4より多くのオカレンスがない場合、最初のオカレンスをスキップしたいと思います。今のところ、最大5つのアンダースコアが発生します。出力A_B、C、D、E、Fを生成する必要があり、以下のコードを使用しました。私はより良い解決策が欲しい。確認してお知らせください。前もって感謝します。最初の出現をスキップして文字列をJavaで分割する

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

これは既に彼が働いている場合、これはコードレビューに属している可能性があります。あなたのスタックはあふれていません。 –

+1

[このデモ](https://ideone.com/2W3PHE)をご覧ください。私はなぜそれが動作するのか分からない。 –

+0

こんにちはWiktor、あなたのポストに感謝します。それは私の必要性を満たすでしょう。私はそれがどのように働くかを確認し理解する。 – Abdul

答えて

1

あなたが分割するために、この正規表現を使用することができます。

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

出力:

[A_B、C、D、E、F]

アイデアがあります"_[A-Z]"が先行する_と一致するようにしてください。最初のものだけが効果的にスキップされます。

あなたは"_"間で異なるフォーマットを持って検討している文字列は、あなたはあなたが\Gに基づいて、この正規表現を使用して、代わりに分割使用マッチングをすることができ、適切な正規表現で

+0

脇の下として、唯一の問題は、もう一度二番目の文字が定義されていない長さになったら、これはもう働きません。しかし、これは例のために完全に動作します。 – SomeJavaGuy

+0

@KevinEsche明らかに、 '[AZ]'は '_ 'の間にあるものと一致するように変更する必要がありますが、アイデアはまったく同じです – Maljam

+0

' * 'や' + 'を使用できないので動作しませんJavaとあなたのソリューションのルック・バックは、4つ以上のものが存在する場合はスキップするという要件を尊重しません。 – Vampire

0

[A-Z]を交換する必要がある場合:

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は、前回の一致の終了時または最初の一致の文字列の開始時に位置をアサートします。

出力:

[A_B, C, D, E, F] 

RegEx Demo

0

私は、分割後にそれを行うだろう。

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

まあ、それは比較的 "シンプル" である:ここでは

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

であるとしても使用することができ、より良い理解のためのコメントとバージョン:

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

ご協力ありがとう – Abdul

+0

よろしくお願いいたします。私はちょうど間違った答えを受け入れたのだろうかと思う – Vampire

0

Javaはありませんが正式に言えば、*+は、制限付き限定子として実装されているため、lookbehindに使用できます。*として{0,0x7FFFFFFF}+として{1,0x7FFFFFFF}Regex look-behind without obvious maximum length in Java参照)。これは、現在のJava 8正規表現エンジンを活用しているので、コードが壊れることがあります。あなたの文字列があまり長くないのであれば、、あなたはJAVA demo

免責を参照してください

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)); 

を使用することができます将来Javaでバグが修正されたときに

+0

4つ以上のアンダースコアがある場合は、最初のアンダースコアのみを無視するという要件を満たしません。私のバージョンはそうです。 – Vampire

+0

これは今や名誉です。 –

+0

今、2つの分割操作が必要ですが、私は1つで動作します。 :-) – Vampire

関連する問題