Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split a string with delimited as pipe (which is not inside double quotes

I have a string like below, which is pipe separated. it has double quotes around string (ex: "ANI").

How do I split this with pipe delimiter (which are not inside double quotes) ?

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

And splitted values shoule be like below:

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

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

Any help would be appreciated!

EDIT

The answer that I accepted, did not work for those strings which has double quotes inside. Any idea, what should be the issue ?

 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)
like image 400
Relativity Avatar asked Oct 23 '15 21:10

Relativity


2 Answers

You can use a regular expression to match the items in the string:

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

Explanation:

(?:       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
like image 88
Guffa Avatar answered Nov 01 '22 11:11

Guffa


Here is one way to do it:

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("\""));
}

This works by splitting everything, and it then joins some of the parts that needs joining by searching for parts that starts with " and corresponding parts that ends with ".

like image 22
Yacoub Massad Avatar answered Nov 01 '22 11:11

Yacoub Massad