【问题标题】:C# Command-Line Parsing of Quoted Paths and Avoiding Escape Characters引用路径的 C# 命令行解析和避免转义字符
【发布时间】:2010-10-28 08:34:12
【问题描述】:

如何解析将被解释为路径的命令行参数? args[] 包含被引用时自动连接的字符串,例如:

example.exe 一二“三四”

args[0] = one
args[1] = two
args[2] = three four

但是,args[] 不会将 "C:\Example\" 属性解析为参数。相反,它将以 "C:\Example"" 的形式提供参数(包括额外的引号。)这是由于路径中的反斜杠被视为转义字符,因此用户在命令中提供的结束引号-line 成为参数的一部分。

.例如:

example.exe 一个 "C:\InputFolder" "C:\OutuptFolder\"

args[0] = one
args[1] = C:\InputFolder"
args[2] = C:\OutputFolder"

一个简单的组合可能是:

_path = args[i].Replace("\"", @"\");

但是,我确信有一个最佳实践。如何正确解析包含路径的命令行,防止 args[] 数组不正确地填充已解析为转义字符的字符串?

注意:我不想在我的项目中包含整个命令行解析库!我只需要处理引用的路径并希望以“手动”方式进行。请不要推荐 NConsoler、Mono 或任何其他大型“厨房水槽”命令行解析库。

另请注意:据我所知,这不是一个重复的问题。虽然其他问题侧重于通用命令行解析,但这个问题专门针对路径在其中的一部分被解释为转义序列时引入的问题。

【问题讨论】:

  • 你在哪里看到这个额外的字符?我正在使用 sn-p 编译器。这是主要的.. 字符串 s=args[0]; Console.WriteLine(s);它可以正常工作。
  • @shahkalpesh:不知道您的 sn-p 编译器,但请尝试从命令行运行它,并为您的程序提供以 \" 结尾的参数(反斜杠双引号)。正如 ebwi 所说,打开我的眼睛。
  • 我现在明白了。抱歉,我没有正确理解输入参数。
  • 更改您的作业流以使用转义反斜杠作为命令行的输入参数。 "\\\\machine\\share\\path\\filename\\" 作为避免此问题的替代方法。

标签: c# command-line escaping


【解决方案1】:

我喜欢你的想法:

_path = args[i].Replace("\"", @"\");

它是干净的,除非问题存在,否则不会有任何效果。

【讨论】:

  • 但是如果你有这将不起作用:example.exe 一个 "C:\InputFolder\" "C:\OutuptFolder\" 因为这两个路径将连接为 arg[1]=C :\InputFolder" C:\Outpurfolder"
【解决方案2】:

不是答案,但这里有一些 background and explanation 来自 Microsoft 在线社区支持的 Jeffrey Tan(2006 年 12 月 7 日):

注意:这不是代码失败 但按照设计,因为反斜杠是 通常用于逃避某些 特殊字符。还有,这 算法与 Win32 命令相同 行参数解析函数 命令行到ArgvW。见备注 下面的部分: http://msdn2.microsoft.com/en-us/library/bb776391.aspx

还参考了 FX 方法 Environment.GetCommandLineArgs 以进一步解释斜线处理行为。

我个人认为这是一个拖累,我很惊讶我以前没有被它咬过。或者也许我知道但不知道?不过,用斜杠盲目替换引号并不是我的解决方案。我正在投票赞成这个问题,因为它让人大开眼界。

【讨论】:

    【解决方案3】:

    我也有同样的挫败感。我的解决方案是使用正则表达式。我的预期输入是路径列表,其中一些可能会被引用。除非最后的所有参数都被引用,否则上述 kludge 不起作用。

    // Capture quoted string or non-quoted strings followed by whitespace
    string exp = @"^(?:""([^""]*)""\s*|([^""\s]+)\s*)+";
    Match m = Regex.Match(Environment.CommandLine, exp);
    
    // Expect three Groups
    // group[0] = entire match
    // group[1] = matches from left capturing group
    // group[2] = matches from right capturing group
    if (m.Groups.Count < 3)
        throw new ArgumentException("A minimum of 2 arguments are required for this program");
    
    // Sort the captures by their original postion
    var captures = m.Groups[1].Captures.Cast<Capture>().Concat(
                   m.Groups[2].Captures.Cast<Capture>()).
                   OrderBy(x => x.Index).
                   ToArray();
    
    // captures[0] is the executable file
    if (captures.Length < 3)
        throw new ArgumentException("A minimum of 2 arguments are required for this program");
    

    谁能看到更高效的正则表达式?

    【讨论】:

      猜你喜欢
      • 2020-02-05
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多