gpt4 book ai didi

c# - 在 C# 中将包含命令行参数的字符串拆分为 string[]

转载 作者:IT王子 更新时间:2023-10-29 03:38:30 26 4
gpt4 key购买 nike

我有一个包含要传递给另一个可执行文件的命令行参数的字符串,我需要提取包含各个参数的字符串[],就像在命令中指定命令时 C# 所做的一样-线。 string[] 将在通过反射执行另一个程序集入口点时使用。

这个有标准函数吗?或者是否有正确拆分参数的首选方法(正则表达式?)?它必须正确处理可能包含空格的 '"' 分隔字符串,所以我不能只在 ' ' 上拆分。

示例字符串:

string parameterString = @"/src:""C:\tmp\Some Folder\Sub Folder"" /users:""abcdefg@hijkl.com"" tasks:""SomeTask,Some Other Task"" -someParam foo";

示例结果:

string[] parameterArray = new string[] { 
@"/src:C:\tmp\Some Folder\Sub Folder",
@"/users:abcdefg@hijkl.com",
@"tasks:SomeTask,Some Other Task",
@"-someParam",
@"foo"
};

我不需要命令行解析库,只是一种获取应该生成的 String[] 的方法。

更新:我必须更改预期结果以匹配 C# 实际生成的结果(删除拆分字符串中多余的“”)

最佳答案

令我恼火的是,没有基于检查每个字符的函数来拆分字符串的函数。如果有,你可以这样写:

    public static IEnumerable<string> SplitCommandLine(string commandLine)
{
bool inQuotes = false;

return commandLine.Split(c =>
{
if (c == '\"')
inQuotes = !inQuotes;

return !inQuotes && c == ' ';
})
.Select(arg => arg.Trim().TrimMatchingQuotes('\"'))
.Where(arg => !string.IsNullOrEmpty(arg));
}

虽然写了那么多,为什么不写必要的扩展方法呢。好吧,你说服了我……

首先,我自己的 Split 版本需要一个函数来决定指定的字符是否应该拆分字符串:

    public static IEnumerable<string> Split(this string str, 
Func<char, bool> controller)
{
int nextPiece = 0;

for (int c = 0; c < str.Length; c++)
{
if (controller(str[c]))
{
yield return str.Substring(nextPiece, c - nextPiece);
nextPiece = c + 1;
}
}

yield return str.Substring(nextPiece);
}

它可能会根据情况产生一些空字符串,但也许这些信息在其他情况下会有用,所以我不会删除此函数中的空条目。

其次(也是更普通的)一个小 helper ,它将从字符串的开头和结尾修剪一对匹配的引号。它比标准的 Trim 方法更挑剔 - 它只会从每一端修剪一个字符,并且不会只从一端修剪:

    public static string TrimMatchingQuotes(this string input, char quote)
{
if ((input.Length >= 2) &&
(input[0] == quote) && (input[input.Length - 1] == quote))
return input.Substring(1, input.Length - 2);

return input;
}

而且我想您也需要一些测试。好吧,那好吧。但这绝对是最后一件事!首先是一个辅助函数,它将拆分结果与预期的数组内容进行比较:

    public static void Test(string cmdLine, params string[] args)
{
string[] split = SplitCommandLine(cmdLine).ToArray();

Debug.Assert(split.Length == args.Length);

for (int n = 0; n < split.Length; n++)
Debug.Assert(split[n] == args[n]);
}

然后我可以这样写测试:

        Test("");
Test("a", "a");
Test(" abc ", "abc");
Test("a b ", "a", "b");
Test("a b \"c d\"", "a", "b", "c d");

这是针对您的要求的测试:

        Test(@"/src:""C:\tmp\Some Folder\Sub Folder"" /users:""abcdefg@hijkl.com"" tasks:""SomeTask,Some Other Task"" -someParam",
@"/src:""C:\tmp\Some Folder\Sub Folder""", @"/users:""abcdefg@hijkl.com""", @"tasks:""SomeTask,Some Other Task""", @"-someParam");

请注意,该实现具有额外的功能,如果有意义,它将删除参数周围的引号(感谢 TrimMatchingQuotes 函数)。我相信这是正常命令行解释的一部分。

关于c# - 在 C# 中将包含命令行参数的字符串拆分为 string[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/298830/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com