2016-03-07 15 views
8

を使用して文字列を文字列の分割スプリットにある:"1","2",3,"4,5"ジャワ:<br></p> <p><code>fieldSeparator : ,</code><br> <code>fieldGrouper : "</code></p> <p>Iは、( ")セパレータとしてカンマ(、)を使用して文字列を分割し、内側の引用符である任意のカンマを無視しなければならない正規表現

次のように私はそれを達成することができています:

String record = "\"1\",\"2\",3,\"4,5\""; 
String[] tokens = record.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); 

出力:

"1" 
"2" 
3 
"4,5" 

今の課題はfieldGrouperは( ")スプリット・トークンの一部であってはならないということです。私はこれのための正規表現を把握することができません。

スプリットの予想される出力は次のようになります。

1 
2 
3 
4,5 
+0

私はこの文字ごとの文字をやっていると思い実際にはより読みやすく、確実に高速になります。アルゴリズムはそれが得られるほど簡単です。遅かれ早かれ出現する可能性が高い '' '例外を処理する方が簡単です。 – Dariusz

+0

不正な形式の擬似JSON入力を使用している理由を聞かせてもらえますか?引用符で囲まれたファンキーネスはこれを扱いにくくし、ソースを整理する方が良いかもしれません。 –

答えて

4

更新:

String[] tokens = record.split("(,*\",*\"*)");

結果:
Image Link

初期ソリューション:それはのペアを分離する非キャプチャグループを使用しています
(?:\\")(.*?)(?:\\")


.split方法@動作しません)

このRexExパターンは、あなたがしたい部分を分離しますエスケープされた引用符、 とその間のすべてを隔離するためのキャプチャグループ。

は、ここでそれをチェックアウト: Live Demo

+2

この正規表現は '3'や' "..." 'で囲まれていない他の値には一致しません。 –

+0

@WiktorStribiżew私は解決策を更新しましたが、私の初期の解決策では、 "#"パターンが一貫していると仮定しました。私は '3'が捕捉されていないことに気付かず、' @rvdが意図的に '3'のために別のフォーマットを持っているのか疑問に思っています。どちらの方法でも、新しいソリューションが機能します。 – Enteleform

+0

申し訳ありませんが、1と2が別々の番号である場合、1,2のような入力に対しては2番目の解決策は機能しません。 –

0

私の提案を:

record = record.replaceAll("\",", "|"); 
record = record.replaceAll(",\\\"", "|"); 
record = record.replaceAll("\"", ""); 

String[] tokens = record.split("\\|"); 

for (String token : tokens) { 
    System.out.println(token); 
} 
2

私の提案:

"([^"]+)"|(?<=,|^)([^,]*) 

regex demoを参照してください。文字列のように"..."と一致し、引用符の間にあるものだけをグループ1に取り込み、文字列の先頭またはコンマの後にグループ以外の文字のグループ2のシーケンスに一致させてキャプチャします。ここで

Java sample codeです:

String s = "value1,\"1\",\"2\",3,\"4,5\",value2"; 
Pattern pattern = Pattern.compile("\"([^\"]+)\"|(?<=,|^)([^,]*)"); 
Matcher matcher = pattern.matcher(s); 
List<String> res = new ArrayList<String>(); 
while (matcher.find()){      // Run the matcher 
    if (matcher.group(1) != null) {   // If Group 1 matched 
     res.add(matcher.group(1));   // Add it to the resulting array 
    } else { 
     res.add(matcher.group(2));   // Add Group 2 as it got matched 
    } 
} 
System.out.println(res); // => [value1, 1, 2, 3, 4,5, value2] 
+0

です。よりよい提案は、彼がソースデータIMHOをクリーンアップすることです。 –

1

私は回避策のこの種のしようとするだろう:

String record = "\"1\",\"2\",3,\"4,5\""; 
record = record.replaceAll("\"?(?<!\"\\w{1,9999}),\"?|\""," "); 
String[] tokens = record.trim().split(" "); 
for(String str : tokens){ 
    System.out.println(str); 
} 

出力:

1 
2 
3 
4,5 
+0

私は最終的に同様の回避策を使用する必要がありました。つまり、各トークンから引用符(存在する場合)を最初に分割して削除します。 – rvd

関連する問題