この正規表現はうまく機能します。バックスラッシュでエスケープされたコンマだけでなく、バックスラッシュでエスケープされたバックスラッシュも正しく認識します。また、生成される一致にはカンマが含まれていません。
/(?:\\\\|\\,|[^,])*/g
(Java 文字列リテラル内でこの正規表現を表す場合、区切り文字を引用符に置き換え、すべてのバックスラッシュを 2 倍にすることを理解して、標準の正規表現表記を使用しています。)
入力例
"apple404, オレンジパイ, 風\,涼しさ, 太陽\\,月, 地球"
この出力を生成します
「りんご404」
「オレンジパイ」
「風\、涼しい」
" 太陽\\"
「ムーン」
「sun」の後の二重バックスラッシュはエスケープされるため、次のコンマはエスケープされないことに注意してください。
この正規表現が機能する方法は、最初に入力を最長のシーケンスに原子化することです。最初に 2 つのバックスラッシュ (可能なマルチバイト文字値の代替の 1 つとして扱います) で始まり、エスケープされたコンマ (2 つ目の可能なマルチバイト文字の代替として扱われます) が続きます。カンマ以外の値で。これらのアトムの任意の数が一致し、その後にリテラル コンマが続きます。
最初の N 個のフィールドを取得するには、前の回答からの一致の配列をスプライスするか、主な式を追加の括弧で囲み、オプションのコンマを含めてフィールド間の内容を一致させ、それをフィールドの先頭に固定します。エンジンがそれ以上 N 個のフィールドのグループを返さないように文字列を変更し、それを数値化します (ここでは N = 5 を使用):
/^((?:\\\\|\\,|[^,])*,?){0,5}/g
繰り返しますが、標準の正規表現表記法を使用していますが、ここでは、これを Java 文字列として引用する簡単な演習も行います。
"^((?:\\\\\\\\|\\\\,|[^,])*,?){0,5}"
これは、OPで指定された正確な要件の両方の部分に実際に答える、このページの唯一のソリューションです。「...カンマとバックスラッシュは、バックスラッシュを使用してエスケープされます。」入力についてはfi\,eld1\\,field2\\,field3\\,field4\\,field5\\,field6\\,
、最初の 5 つのフィールドのみが適切に一致しますfi\,eld1\\,field2\\,field3\\,field4\\,field5\\,
。
注:私の最初の回答は、OPの元のコードとサンプルデータの暗黙の一部である同じ仮定を作成しました。これには、すべてのフィールドに続くコンマが必要でした。問題は、入力が正確に 5 フィールド以下であり、最後のフィールドの後にコンマが続いていない場合 (同等に空のフィールドが続く場合)、最終フィールドが一致しないことでした。私はこれが気に入らなかったので、両方の回答を更新して、次のコンマを必要としないようにしました。
この回答の欠点は、コンマ間の値に「何か」とエスケープされたコンマまたはエスケープされたバックスラッシュが含まれるというOPの仮定に従うことです(つまり、二重引用符などの文字列は区別されず、エスケープされたコンマとバックスラッシュのみが認識されます)。私の答えは、その架空のシナリオの基準を満たしています。しかし実際には、円記号を使用せずにフィールド内にカンマを含めるために、CSV フィールドを二重引用符で囲むことができると考える人もいるでしょう。
したがって、@anubhava の言葉を繰り返し、CSV データを処理するときは常に「本物の」CSV パーサーを使用することを提案します。それ以外のことを行うのは、スクリプトのキディであり、CSV データを真に「処理」することではありません。