3

次のように定義された正規表現パターンがあります

var pattern = ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))";

と私はフィールドを取得するために文字列のようないくつかのCSVを分割しようとしています

この正規表現で機能する文字列の例は次のとおりです。

_input[0] = ""; // expected single blank field
_input[1] = "A,B,C"; // expected three individual fields
_input[2] = "\"A,B\",C"; // expected two fields 'A,B' and C
_input[3] = "\"ABC\"\",\"Text with,\""; // expected two fields, 'ABC"', 'Text with,'
_input[4] = "\"\",ABC\",\"next_field\""; // expected two fields, '",ABC', 'next_field'

ただし、これは機能していません

_input[5] = "\"\"\",ABC\",\"next_field\"";

私は3つの分野を期待しています

'"', 'ABC"', 'next_field'

しかし、私は2つのフィールドを取得しています

'"",ABC', 'next_field'

誰かがこの正規表現を手伝ってもらえますか?

奇妙な部分は、2番目の列の値の最初と最後に引用符がなく、最後にあることだと思います。したがって、最初の列の値は空で、2番目の列はABCです。」

ありがとう、ロブ

4

1 に答える 1

3

要件が互いに矛盾しているように見えるため、二重引用符の処理方法に関して、ロジックをさらに具体的にする必要があると思います。

あなたが達成しようとしていることに最も近いと思う私のクイックバージョンはこれです(注1)正規表現を検証するために外部ツールを使用しているため、二重引用符のエスケープが欠落しています、および2)取得方法を変更しました一致した値。例については下部を参照してください):

(?<Match>(?:"[^"]*"+|[^,])*)(?:,(?<Match>(?:"[^"]*"+|[^,])*))*

次のロジックがあります。

  • 二重引用符がある場合は、最後の二重引用符がヒットするまで、すべてを含めます。
  • 二重引用符の終わりに達すると、直後に続く二重引用符も含まれます。
  • 次の文字がコンマ以外の場合は、それが含まれ、上記が再度テストされます。
  • カンマの場合、現在の一致が終了し、コンマの後に新しい一致が始まります。

ただし、上記のロジックは、インデックス4および5に期待するものと矛盾します。

[4] = '""' and 'ABC","next_field"'
[5] = '"""' and 'ABC","next_field"'

上記のロジックがニーズ/期待に対して間違っている理由を指摘できる場合は、完全に機能する正規表現を使用して回答を編集します。

値を取得するには、次のようにします。

string pattern = @"(?<Match>(?:""[^""]*""+|[^,])*)(?:,(?<Match>(?:""[^""]*""+|[^,])*))*";

string[] testCases = new[]{
  @"",
  @"A,B,C",
  @"A,B"",C",
  @"ABC"",""Text with,",
  @""",ABC"",""next_field""",
  @""""",ABC"",""next_field"""
};

foreach(string testCase in testCases){
  var match = System.Text.RegularExpressions.Regex.Match(testCase, pattern);
  string[] matchedValues = match.Groups["Match"].Captures
    .Cast<System.Text.RegularExpressions.Capture>()
    .Select(c => c.Value)
    .ToArray();
}
于 2012-12-10T07:57:50.447 に答える