【问题标题】:Parse command line string into a list of strings [closed]将命令行字符串解析为字符串列表[关闭]
【发布时间】:2017-05-16 11:57:15
【问题描述】:

我想将以下字符串作为输入:

first-arg second-arg "third arg with spaces" "arg with \" quotes"

并将这个字符串列表作为输出返回

["first-arg", "second-arg", "third arg with spaces", "arg with \" quotes"]

是否有任何 nuget 包或内置函数可以做到这一点?我希望它能够处理边缘情况,例如包含多个单词的参数和包含引号的参数。

【问题讨论】:

  • 我使用了一个叫做 Consolas 的工具来做这样的事情。那是很久以前的事了,所以我不记得它到底能做什么。 nuget.org/packages/Consolas
  • 这很难做还是怎么回事?我能看到的唯一例外是序列\",例如,您可以用"分割/查找/任何东西之前替换它。
  • 一个好的 CSV 解析器应该会为您处理。
  • 既然在你的标题中你说“解析命令行字符串”那么你实际上不需要做任何事情。如果您提供的有问题的行作为命令行参数传递给您的应用程序 - 它将在 Main(string[] arguments) 函数中正确解析为具有 4 个元素的数组。

标签: c#


【解决方案1】:
string[] arguments = Environment.GetCommandLineArgs();

欲了解更多信息,请参阅MSDN website

【讨论】:

    【解决方案2】:

    这个类满足要求。这不是最有效的方法,但它会返回正确的参数。

    public static class ArgumentLineParser
    {
        public static string[] ToArguments(string cmd)
        {
            if (string.IsNullOrWhiteSpace(cmd))
            {
                return new string[0];
            }
    
            var argList = new List<string>();
            var parseStack = new Stack<char>();
            bool insideLiteral = false;
    
            for (int i = 0; i < cmd.Length; i++)
            {
                bool isLast = i + 1 >= cmd.Length;
    
                if (char.IsWhiteSpace(cmd[i]) && insideLiteral)
                {
                    // Whitespace within literal is kept
                    parseStack.Push(cmd[i]);
                }
                else if (char.IsWhiteSpace(cmd[i]))
                {
                    // Whitespace delimits arguments
                    MoveArgumentToList(parseStack, argList);
                }
                else if (!isLast && '\\'.Equals(cmd[i]) && '"'.Equals(cmd[i + 1]))
                {
                    //Escaped double quote
                    parseStack.Push(cmd[i + 1]);
                    i++;
                }
                else if ('"'.Equals(cmd[i]) && !insideLiteral)
                {
                    // Begin literal
                    insideLiteral = true;
                }
                else if ('"'.Equals(cmd[i]) && insideLiteral)
                {
                    // End literal
                    insideLiteral = false;
                }
                else
                {
                    parseStack.Push(cmd[i]);
                }
            }
    
            MoveArgumentToList(parseStack, argList);
    
            return argList.ToArray();
        }
    
        private static void MoveArgumentToList(Stack<char> stack, List<string> list)
        {
            var arg = string.Empty;
            while (stack.Count > 0)
            {
                arg = stack.Pop() + arg;
            }
    
            if (arg != string.Empty)
            {
                list.Add(arg);
            }
        }
    }
    

    可以这样使用:

    var line = @"first-arg second-arg ""third arg with spaces"" ""arg with \"" quotes""";
    var args = ArgumentLineParser.ToArguments(line);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-30
      • 2011-09-19
      • 2019-09-04
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 2015-10-28
      • 2016-02-21
      相关资源
      最近更新 更多