繁体   English   中英

命令行(类csc编译器)解析

[英]Command line(csc-like compiler) parsing

我正在寻找一个算法/库来解析这个命令行:

var cmd = "foo /option:value /option2:valueof /etc:.. baa /t:4 etc xd";

至:

foo => { "option", "value" },
       { "option2", "valueof" },
       {"etc", ".."},
baa => {"t", "4"},
etc => {"xd", ""},

我尝试使用if和for,尝试'纯模式'(C-like)。 但是非常感谢使用正则表达式或linq的解决方案。

我的代码(不起作用):

var cmd = "foo /option:value /option2:valueof /etc:.. baa /t:4 etc xd";
            var keys = new Dictionary<string, Dictionary<string,string>>();

            for (int pos = 0, len = cmd.Length; pos < len; pos++)
            {
                StringBuilder buffer = new StringBuilder();
                char c = cmd[pos];

                if (c == '/') 
                {
                    StringBuilder optionName = new StringBuilder();
                    StringBuilder optionValue = new StringBuilder();

                    do
                    {
                        c = cmd[pos++];

                        if (c == ':')
                        {
                            do
                            {
                                c = cmd[pos++];
                                optionValue.Append(c);

                            } while (c != '/' || c != ' ');
                        }
                        else
                        {
                            optionName.Append(c);
                        }

                    } while (c != ' ');

                    keys.Add(buffer.ToString(),
                        new Dictionary<string, string>
                        {
                            {optionName.ToString(), optionValue.ToString()}
                        });
                }
            }

它给出的Index was outside the bounds of the array.

提前致谢。

肯定有库来处理命令行解析( SO建议NDesk,但我没有亲自使用它 )。

我会在整个字符串中逐个字符地使用string.Split()

            var tokenCmd = cmd.Split(' ');
            string currentKey = "";

            foreach (var token in tokenCmd)
            {
                if ((char.IsLetterOrDigit(token[0])) &&
                    (!keys.ContainsKey(currentKey)) ||
                    (keys[currentKey].Any()))
                {
                    currentKey = token;
                    keys.Add(currentKey,
                             new Dictionary<string, string>());
                }
                else
                {
                    var splitToken = new[] { token, "" };

                    if (token.Contains(':'))
                    {
                        splitToken = token
                            .Replace("/", "")
                            .Split(':');
                    }

                    keys[currentKey].Add(splitToken[0],
                                         splitToken[1]);
                }
            }

更改:

} while (c != '/' || c != ' '); 

至:

} while (c != '/' && c != ' '); 

如果可以保留命令行分开(它们在输入var中在一起)并保留args出现的string []对象类型,那么我认为这是您要查找的机器人:

static void Main(string[] args)
{
    Hashtable parsedArgs = new Hashtable();
    args.ToList().ForEach(x => {
        int dpos = x.IndexOf(":");
        if (dpos > -1)
            parsedArgs[x.Substring(1, dpos - 1)] = x.Substring(dpos + 1);
        else
            parsedArgs[x.Substring(1)] = true;
    });
}

编辑:将Linq修改为Hashtable,如下所示。 Hashtable比我原来的答案中更优雅的(更少的代码)KeyValuePair <>更容易使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM