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

发布于 2025-01-05 03:59:34 字数 1827 浏览 1 评论 0原文

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

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

to:

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

我尝试在“纯模式”(类似C)中仅使用if和for。但是使用正则表达式或 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()}
                        });
                }
            }

它给出了一个索引超出了数组的范围。

提前致谢。

I'm looking for an algorithm/library to parse this command line:

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

to:

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

I tried in 'pure mode'(C-like) just using if and for. But an solution with regular expression or linq is very appreciated.

my code(not working):

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

it given an Index was outside the bounds of the array.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一绘本一梦想 2025-01-12 03:59:34

当然有一些库可以处理命令行解析(SO 推荐 NDesk ,但我个人没有使用过)。

我会使用 字符串。 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]);
                }
            }

There are certainly libraries to handle command-line parsing (SO recommends NDesk, but I haven't personally used it).

I'd use string.Split() over iterating character by character through the string.

            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]);
                }
            }
独孤求败 2025-01-12 03:59:34

更改:

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

至:

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

change:

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

to:

} while (c != '/' && c != ' '); 
生寂 2025-01-12 03:59:34

如果您可以保留将命令行分开(它们在您的输入变量中一起压缩)并保留参数传入的 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 转换为哈希表,如下所示。哈希表比看起来更优雅(代码更少)的 KeyValuePair<> 更容易使用。在我原来的答案中。

If you can retain keep the command lines separate (they're tarred together in your input var) and retain the string[] object type that the args came in on then I think this is the droid you're looking for:

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;
    });
}

Edit: Revised to Linq into a Hashtable as shown here. The Hashtable is much easier to work with than the more elegant-seeming (less code) KeyValuePair<> in my original answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文