§ August 8, 2006

A Command Line style string parser (in C#)

Last week I was writing a service that could be run as a console app. I needed to be able to parse a single string into an array like the shell does for command line apps, and the service does for start parameters. I did a little googling, but found only command line arg classes that put command line args into associative array's for easy indexing, which isn't what I was looking for.

The class had basically 2 requirements:
  1. It had to be able to split the string on spaces (simple right?)
  2. It had to escape spaces that were quoted (as well as quotes that were escaped).
First I tried to iterate through the string a character at a time, looking for spaces keeping the state of whether we were inside a quote or not, whether the current character was an escaped quote, and so on.

That was a major pain, so I stepped back and rethought my algorithm. this is what I ended up with, which was much simplier, and did exactly what I wanted without a lot of fuss.

So here's my command line parser:
public class CommandLineParser {
    CommandLineParser() { }
    public static string[] Parse(string str) {        
        if(str == null || !(str.Length > 0)) return new string[0];
        int idx = str.Trim().IndexOf(" "); 
        if(idx == -1) return new string[] { str };
        int count = str.Length;
        ArrayList list = new ArrayList(); 
        while(count > 0) {
            if(str[0] == '"') {
                int temp = str.IndexOf("\"", 1, str.Length - 1);
                while(str[temp - 1] == '\\') {
                    temp = str.IndexOf("\"", temp + 1, str.Length - temp - 1);
                }
                idx = temp+1;
            }
            if(str[0] == '\'') {   
                int temp = str.IndexOf("\'", 1, str.Length - 1);
                while(str[temp - 1] == '\\') {
                    temp = str.IndexOf("\'", temp + 1, str.Length - temp - 1);
                }
                idx = temp+1;
            }
            string s = str.Substring(0, idx);
            int left = count - idx;
            str = str.Substring(idx, left).Trim();
            list.Add(s.Trim('"'));
            count = str.Length;
            idx = str.IndexOf(" ");
            if(idx == -1) {
                string add = str.Trim('"', ' ');
                if(add.Length > 0) {
                    list.Add(add);
                }
                break;
            }
        }
        return (string[])list.ToArray(typeof(string));
    }
}

Posted 19 years, 11 months ago on August 8, 2006

 Comments can be posted in the forums.

© 2003 - 2024 NullFX
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License