1

I would like to split a string deliminated by a character such as ‘&’, but in the case where some values contain the deliminator I would like to escape with double quotes. What is an elegant approach to splitting while ignoring the deliminating characters that have been escaped while also accounting for escape character escapes?

For example split this string properly

var1=asdfasdf&var2=contain””quote&var3=”contain&delim”&var4=”contain””both&”

Into:

var1=asdfasdf
var2=contain"quote
var3=contain&delim
var4=contain"both&

Incidentally, I am thinking Regex...

ccook
  • 5,869
  • 6
  • 56
  • 81
  • Is there a particular reason that you want to use the double-quote as an escape character? In your example you only seem to use it to escape itself. Also should there be an & between 'delim"' and 'var4='? – Lazarus Mar 11 '09 at 16:26
  • The characters them selves are actually arbitrary, that is the default however. and yes, they should be one between, ty! :) – ccook Mar 11 '09 at 16:27
  • Appears to be a duplicate of [this one](http://stackoverflow.com/questions/634777/c-extension-method-string-split-that-also-accepts-an-escape-character/) That's two very similar questions within about an hour. Is this a programming challenge on someone's blog? – James Curran Mar 11 '09 at 16:27

1 Answers1

0

My solution, with test:

    void TestCharlesParse()
    {
        string s = @"var1=asdfasdf&var2=contain""""quote&var3=""contain&delim""&var4=""contain""""both&""";
        string[] os = CharlesParse(s);

        for (int i = 0; i < os.Length; i++)
            System.Windows.Forms.MessageBox.Show(os[i]);
    }

    string[] CharlesParse(string inputString)
    {
        string[] escapedQuotes = { "\"\"" };

        string[] sep1 = inputString.Split(escapedQuotes, StringSplitOptions.None);

        bool quoted = false;
        ArrayList sep2 = new ArrayList();
        for (int i = 0; i < sep1.Length; i++)
        {
            string[] sep3 = ((string)sep1[i]).Split('"');
            for (int j = 0; j < sep3.Length; j++)
            {
                if (!quoted)
                {
                    string[] sep4 = sep3[j].Split('&');
                    for (int k = 0; k < sep4.Length; k++)
                    {
                        if (k == 0)
                        {
                            if (sep2.Count == 0)
                            {
                                sep2.Add(sep4[k]);
                            }
                            else
                            {
                                sep2[sep2.Count - 1] = ((string)sep2[sep2.Count - 1]) + sep4[k];
                            }
                        }
                        else
                        {
                            sep2.Add(sep4[k]);
                        }
                    }
                }
                else
                {
                    sep2[sep2.Count - 1] = ((string)sep2[sep2.Count - 1]) + sep3[j];
                }
                if (j < (sep3.Length-1))
                    quoted = !quoted;
            }
            if (i < (sep1.Length - 1))
                sep2[sep2.Count - 1] = ((string)sep2[sep2.Count - 1]) + "\"";
        }

        string[] ret = new string[sep2.Count];
        for (int l = 0; l < sep2.Count; l++)
            ret[l] = (string)sep2[l];

        return ret;
    }