Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#命令行解析带引号的路径并避免转义字符_C#_Command Line_Escaping - Fatal编程技术网

C#命令行解析带引号的路径并避免转义字符

C#命令行解析带引号的路径并避免转义字符,c#,command-line,escaping,C#,Command Line,Escaping,如何解析要解释为路径的命令行参数?args[]包含在引用时自动连接的字符串,例如: example.exe一二“三四” 但是,args[]不会将“C:\Example\”属性解析为参数。相反,它将提供参数“C:\Example”“(包括额外的引号)。这是由于路径中的反斜杠被视为转义字符,因此用户在命令行上提供的结束引号将成为参数的一部分 例如: example.exe一个“C:\InputFolder”“C:\OutUpFolder\” 一个简单的难题可能是: _path = args[i].R

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

example.exe一二“三四”

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

例如:

example.exe一个“C:\InputFolder”“C:\OutUpFolder\”

一个简单的难题可能是:

_path = args[i].Replace("\"", @"\");
但是,我相信这有一个最佳实践。如何正确解析包含路径的命令行,防止args[]数组不正确地填充已解析为转义字符的stings

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

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

我喜欢你的想法:

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

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

不是答案,但下面是来自Jeffrey Tan的一些,Microsoft在线社区支持(12/7/2006):

注意:这不是代码失败 但出于设计,因为反斜杠是 通常用来逃避某些危险 特殊角色。还有,这个 算法与Win32命令相同 行参数解析函数 命令行到argvw。请参见备注 下节:

还参考FX方法进一步解释斜杠处理行为


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

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

// 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");
//捕获带引号的字符串或不带引号的字符串,后跟空格
字符串exp=@“^(?:([^”“]*)”\s*|([^”“\s]+)\s*)+”;
Match m=Regex.Match(Environment.CommandLine,exp);
//预计有三组
//组[0]=整个匹配
//组[1]=来自左侧捕获组的匹配项
//组[2]=来自右捕获组的匹配项
如果(m.Groups.Count<3)
抛出新ArgumentException(“此程序至少需要2个参数”);
//按原始位置对捕获进行排序
var captures=m.Groups[1]。captures.Cast().Concat(
m、 组[2]。捕获.Cast()。
OrderBy(x=>x.Index)。
ToArray();
//捕获[0]是可执行文件
如果(长度<3)
抛出新ArgumentException(“此程序至少需要2个参数”);

有人能看到更高效的正则表达式吗?

您在哪里看到这个额外的字符?我正在使用代码段编译器。这是main..string s=args[0];Console.WriteLine(s);它可以正常工作。@shahkalpesh:Dunno不知道您的代码段编译器,但请尝试从命令行运行它,并为您的程序提供一个以\(反斜杠双引号)结尾的参数。正如埃维所说,我睁开了眼睛。我现在明白了。很抱歉,我没有正确理解输入参数。请将作业流更改为在命令行上对输入参数使用转义反斜杠。“\\\\machine\\share\\path\\filename\\”作为避免此问题的替代方法。但如果您有:example.exe一个“C:\InputFolder\”“C:\OutputFolder\”,则此操作将不起作用,因为这两个路径将合并为arg[1]=C:\InputFolder“C:\Outpurfolder”
_path = args[i].Replace("\"", @"\");
// 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");