引用路径的 C# 命令行解析和避免转义字符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/900087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 22:09:20  来源:igfitidea点击:

C# Command-Line Parsing of Quoted Paths and Avoiding Escape Characters

c#command-lineescaping

提问by James

How is it possible to parse command-line arguments that are to be interpreted as paths? args[] contains strings that are automatically joined if they are quoted, e.g.:

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

example.exe one two "three four"

example.exe 一二“三四”

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

However, args[] will not property parse "C:\Example\" as an argument. Rather, it will supply the argument as "C:\Example"" (with the extra quote included.) This is due to the backslash in the path being treated as an escape character and thus the end quotation that the user supplied on the command-line becomes part of the argument.

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

.e.g:

。例如:

example.exe one "C:\InputFolder" "C:\OutuptFolder\"

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

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

An easy kludge might be:

一个简单的混搭可能是:

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

However, I'm sure there is a best-practice for this. How might one correctly parse a command line that inlcudes paths, preventing the args[] array from improperly being populated with stings that have been parsed for escape characters?

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

NOTE: I would not like to include an entire command-line parsing library in my project! I need only to handle quoted paths and wish to do so in a "manual" fashion. Please do not reccomend NConsoler, Mono, or any other large "kitchen sink" command-line parsing library.

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

ALSO NOTE: As far as I can tell, this is not a duplicate question. While other questions focus on generic command-line parsing, this question is specific to the problem that paths introduce when parts of them are interpreted as escape sequences.

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

采纳答案by ewbi

Not an answer, but here's some background and explanationfrom Jeffrey Tan, Microsoft Online Community Support (12/7/2006):

不是答案,但以下是Microsoft 在线社区支持 (12/7/2006) Jeffrey Tan的一些背景和解释

Note: this is not not a code defeat but by design, since backslashe are normally used to escape certain special character. Also, this algorithm is the same as Win32 command line arguments parsing function CommandLineToArgvW. See the Remarks section below: http://msdn2.microsoft.com/en-us/library/bb776391.aspx

注意:这不是代码失败而是设计使然,因为反斜杠通常用于转义某些特殊字符。此外,该算法与 Win32 命令行参数解析函数 CommandLineToArgvW 相同。请参阅下面的备注部分:http: //msdn2.microsoft.com/en-us/library/bb776391.aspx

Also makes reference to the FX method Environment.GetCommandLineArgsfor further explanation of the slash handling behavior.

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

Personally I think this is a drag, and I'm surprised I haven't been bit by it before. Or maybe I have and don't know it? Blind replacement of quotes with slashes doesn't strike me as a solution, though. I'm voting the question up, because it was an eye opener.

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

回答by Robert Harvey

I like your idea:

我喜欢你的想法:

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

It is clean, and will have no effect unless the problem exists.

它是干净的,除非问题存在,否则不会产生任何影响。

回答by Terrence

I had the same frustration. My solution was to use regular expressions. My expected input is a list of paths, some of which may be quoted. The above kludge doesn't work unless all the last arguments are quoted.

我也有同样的挫败感。我的解决方案是使用正则表达式。我的预期输入是路径列表,其中一些可能会被引用。除非引用所有最后一个参数,否则上述 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");

Can anyone see a more efficient regex?

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