将命令行字符串解析为字符串列表

时间:2017-05-16 11:57:16

标签: c#

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

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

并将此字符串列表作为输出

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

是否有任何nuget包或内置函数可以执行此操作?我希望它处理边缘情况,就像包含多个单词和包含引号的参数的参数一样。

2 个答案:

答案 0 :(得分:0)

string[] arguments = Environment.GetCommandLineArgs();

有关详细信息,请参阅MSDN website

答案 1 :(得分:0)

此课程符合要求。它不是最有效的方式,但它会返回正确的参数。

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