如何解析命令行参数

bri*_*ler 4 c# command-line

我想解析一组看起来像这样的命令行参数:

-p[project file path] -s[name 1]=[value 1] ... -s[name n]=[value n]
Run Code Online (Sandbox Code Playgroud)

只有一个项目p和任意数量的设置s.

我试过用 NDesk.Options

var set = new OptionSet {
    { "p=", "the project file", v => { /* do stuff */ } },
    { "s=", "a setting", (m, v) =>  { /* do stuff */ } },
};
Run Code Online (Sandbox Code Playgroud)

这在大多数情况下效果很好,但是当value文件路径(甚至引用)时\,解析器会将所有内容都放到右边.我通过覆盖OptionSet我继承的自己的类的解析方法来解决这个问题NDesk.Options.OptionSet,但我想知道是否有任何库可以开箱即用地处理这种功能?

UPDATE

对不起,这不是\我认为:无论如何一组失败的例子是:

-sSetting=C:\Temp
-sSetting="C:\Temp"
-s"Setting=C:\Temp"
Run Code Online (Sandbox Code Playgroud)

他们都失败了 OptionException Error: Found 3 option values when expecting 2.

Jea*_*nal 5

更新:更新以处理设置值中的冒号.

好了,在这里你碰到的隐性违约的一个NDesk.Options,这是在多值参数,都:=被认为是值分隔符,这个含义Setting=C:\Path解析为3个值(设定,C,\路径),而不是你的预期二.

为了解决这个问题,你只需要修改-s选项定义,只考虑=作为有效的分隔符,"s={=}"而不是写"s=".

原来的答案,当它是关于反斜杠.

我使用了NDesk.Options,没有遇到引用路径和反斜杠的任何问题.

这是我的示例程序:

public static void Main(string[] args)
{
    string parsedPath = null;
    Dictionary<string, string> parsedValues = new Dictionary<string, string>();
    var set = new OptionSet() 
    { 
        { "p=", "the project path", v => parsedPath = v }, 
        { "s=", "a setting", (m, v) => { parsedValues.Add(m, v); } },
    };
    set.Parse(args);
    Console.WriteLine(parsedPath ?? "<NULL>");
    foreach (var keyValuePair in parsedValues)
    {
        Console.WriteLine(keyValuePair.Key + "::::" + keyValuePair.Value);
    }
}
Run Code Online (Sandbox Code Playgroud)

您将看到定义与我的定义之间存在差异:p=意味着该选项具有必需值,而您的定义意味着该定义p是布尔标志值.

我没有遇到任何有关反斜杠的问题,无论是在p设置还是在s设置中.您是否可以尝试使用NDesk.Options版本0.2.1运行程序并显示哪些值失败?

以下是我运行的一些示例,这些示例都已成功解析:

-p=..\Path
-p..\Path
-pC:\Hello
-pHello\World
-p"Hello\World"
-s"Greeting=Hello\World"
-sGreeting="Hello\World"
-sGreeting=Hello\World
-sGreeting="Hello\My World"
-s"Greeting=Hello\My World"
Run Code Online (Sandbox Code Playgroud)

这里有一些解析确实会产生另一个值得一提的结果:

-sGreeting=Hello\My World -- // This gives Greeting="Hello\My" 
Run Code Online (Sandbox Code Playgroud)

注意:如果这改变了什么,我在项目中使用Options.cs源代码文件运行NDesk.Options,而不是使用编译的DLL.