如何拆分分隔为管道的字符串(不在双引号内

时间:2015-10-23 21:41:45

标签: c# regex string split delimiter

我有一个像下面这样的字符串,它是管道分隔的。它在字符串周围有双引号(例如:“ANI”)。

如何使用管道分隔符(不在双引号内)拆分它?

511186|"ANI"|"ABCD-102091474|E|EFG"||"2013-07-20 13:47:19.556"

分裂价值应该如下:

511186
"ANI"
"ABCD-102091474|E|EFG"

"2013-07-20 13:47:19.556"

任何帮助将不胜感激!

修改

我接受的答案对于那些内部有双引号的字符串不起作用。任何想法,应该是什么问题?

 using System.Text.RegularExpressions;
 string regexFormat = string.Format(@"(?:^|\{0})(""[^""]*""|[^\{0}]*)", '|');
string[] result = Regex.Matches("111001103|\"E\"|\"BBB\"|\"XXX\"|||10000009|153086649|\"BCTV\"|\"REV\"|||1.00000000|||||\"ABC-BT AD\"|\"\"\"ABC - BT\"\" AD\"|||\"N\"||\"N\"|||\"N\"||\"N",regexFormat)
  .Cast<Match>().Select(m => m.Groups[1].Value).ToArray();
  foreach(var i in result)
  Console.WriteLine(i)

4 个答案:

答案 0 :(得分:2)

您可以使用正则表达式来匹配字符串中的项目:

string[] result = Regex.Matches(s, @"(?:^|\|)(""[^""]*""|[^|]*)")
  .Cast<Match>()
  .Select(m => m.Groups[1].Value)
  .ToArray();

说明:

(?:       A non-capturing group
^|\|      Matches start of string or a pipe character
)         End of group
(         Capturing group
"[^"]*"   Zero or more non-quotes surrounded by quotes
|         Or
[^|]*     Zero or more non-pipes
)         End of group

答案 1 :(得分:1)

这是一种方法:

public List<string> Parse(string str)
{
    var parts = str.Split(new[] {"|"}, StringSplitOptions.None);

    List<string> result = new List<string>();

    for (int i = 0; i < parts.Length; i++)
    {
        string part = parts[i];

        if (IsPartStart(part))
        {
            List<string> sub_parts = new List<string>();

            do
            {
                sub_parts.Add(part);
                i++;
                part = parts[i];
            } while (!IsPartEnd(part));

            sub_parts.Add(part);

            part = string.Join("|", sub_parts);
        }

        result.Add(part);
    }

    return result;

}

private bool IsPartStart(string part)
{
    return (part.StartsWith("\"") && !part.EndsWith("\"")) ;
}

private bool IsPartEnd(string part)
{
    return (!part.StartsWith("\"") && part.EndsWith("\""));
}

这可以通过拆分所有内容来实现,然后通过搜索以"开头的部分和以"结尾的相应部分来加入一些需要加入的部分。

答案 2 :(得分:0)

string.Split("|", inputString);

...将为您提供单独的部件,但如果任何部件中有管道分隔器,则会失败。

如果它是一个CSV文件,遵循关于字符转义的所有常规CSV规则等(但使用管道符号而不是逗号),那么您应该查看使用CsvHelper,一个专为此设计的NuGet包读写CSV文件。它完成了所有艰苦的工作,并处理了你自己必须做的所有角落案件。

答案 3 :(得分:0)

我是这样做的。这很简单,我想你会发现它也很快。我没有运行任何测试,但我相信它比正则表达式更快。<​​/ p>

IEnumerable<string> Parse(string s)
{
    int pos = 0;

    while (pos < s.Length)
    {
        char endChar = '|';

        // Test for quoted value
        if (s[pos] == '"')
        {
            pos++;
            endChar = '"';
        }

        // Extract this value
        int newPos = s.IndexOf(endChar, pos);
        if (newPos < 0)
            newPos = s.Length;
        yield return s.Substring(pos, newPos - pos);

        // Move to start of next value
        pos = newPos + 1;
        if (pos < s.Length && s[pos] == '|')
            pos++;
    }
}