[英]How do I convert spaces, except for those within quotes, to commas in C#?
[英]How do I split a string by spaces except if in single or double quotes
我意識到這個問題已經在這里被問過很多次了。 我已經查看並嘗試了許多答案,但沒有一個對我有用。
我正在使用 C# 創建一個可以接受命令行 arguments 的應用程序。 例如
Start -p:SomeNameValue -h
DisplayMessage -m:Hello
DisplayMessage -m:'Hello World'
DisplayMessage -m:"Hello World"
我的 args 以單個字符串的形式出現。 我需要用空格分隔,除非有單引號或雙引號。 所以上面的結果會是
Start
-p:SomeNameValue
-h
DisplayMessage
-m:Hello
DisplayMessage
-m:'Hello World'
DisplayMessage
-m:"Hello World"
我在這里找到的答案似乎被打破了。 例如,他們刪除:
字符或者根本不工作。 我嘗試過的一些代碼如下:
var res1 = Regex.Matches(payload, @"[\""].+?[\""]|[^ ]+")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
var res2 = payload.Split('"')
.Select((element, index) => index % 2 == 0
? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
: new string[] { element }) // Keep the entire item
.SelectMany(element => element).ToList();
var res3 = Regex
.Matches(payload, @"\w+|""[\w\s]*""")
.Cast<Match>()
.Select(m => m.Groups["match"].Value)
.ToList();
string[] res4 = Regex.Split(payload, ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
Regex regex = new Regex(@"\w+|""[\w\s]*""");
var res5 = regex.Matches(payload).Cast<Match>().ToList();
我只是想按照上面的方法將 arg 分成塊。
這是一個簡單的演示程序,我認為它通過解析字符串完全符合您的要求。
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
string[] testStrings = new string[] {
"Start -p:SomeNameValue -h",
"DisplayMessage -m:Hello",
"DisplayMessage -m:'Hello World'",
"DisplayMessage -m:\"Hello World\"",
"DisplayMessage -m:\"'Inside double quotes'\"",
"DisplayMessage -m:'\"Inside single quotes\"'"
};
foreach (string str in testStrings)
{
Console.WriteLine(str);
string[] parsedStrings = ParseString(str);
for (int i = 0; i < parsedStrings.Length; i++)
{
Console.WriteLine(" " + (i + 1) + ". " + parsedStrings[i]);
}
Console.WriteLine();
}
}
private static string[] ParseString(string str)
{
var retval = new List<string>();
if (String.IsNullOrWhiteSpace(str)) return retval.ToArray();
int ndx = 0;
string s = "";
bool insideDoubleQuote = false;
bool insideSingleQuote = false;
while (ndx < str.Length)
{
if (str[ndx] == ' ' && !insideDoubleQuote && !insideSingleQuote)
{
if (!String.IsNullOrWhiteSpace(s.Trim())) retval.Add(s.Trim());
s = "";
}
if (str[ndx] == '"') insideDoubleQuote = !insideDoubleQuote;
if (str[ndx] == '\'') insideSingleQuote = !insideSingleQuote;
s += str[ndx];
ndx++;
}
if (!String.IsNullOrWhiteSpace(s.Trim())) retval.Add(s.Trim());
return retval.ToArray();
}
}
該程序將產生以下 output:
Start -p:SomeNameValue -h
1. Start
2. -p:SomeNameValue
3. -h
DisplayMessage -m:Hello
1. DisplayMessage
2. -m:Hello
DisplayMessage -m:'Hello World'
1. DisplayMessage
2. -m:'Hello World'
DisplayMessage -m:"Hello World"
1. DisplayMessage
2. -m:"Hello World"
DisplayMessage -m:"'Inside double quotes'"
1. DisplayMessage
2. -m:"'Inside double quotes'"
DisplayMessage -m:'"Inside single quotes"'
1. DisplayMessage
2. -m:'"Inside single quotes"'
一種方法是使用循環來檢查包含雙引號分隔符的項目,並使用標志變量來確定我們是在帶引號的字符串內部還是外部。 如果我們在帶引號的字符串中,請將當前部分添加到臨時變量中。 當我們退出引用的字符串時,將臨時變量添加到我們的 arguments 集合中。
我認為代碼更不言自明。 請注意,我只允許雙引號用空格分隔參數。 如果您也想允許單引號,則可以將其添加到代碼中:
public static List<string> GetArgs(string cmdLine)
{
var args = new List<string>();
if (string.IsNullOrWhiteSpace(cmdLine)) return args;
var parts = cmdLine.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
var openQuote = false;
var currentPart = new StringBuilder();
foreach (var part in parts)
{
if (part.Count(c => c == '"') % 2 == 1)
{
if (currentPart.Length > 0) currentPart.Append(" ");
currentPart.Append(part);
if (openQuote)
{
args.Add(currentPart.ToString());
currentPart.Clear();
}
openQuote = !openQuote;
}
else if (openQuote)
{
if (currentPart.Length > 0) currentPart.Append(" ");
currentPart.Append(part);
}
else
{
args.Add(part);
}
}
if (currentPart.Length > 0) args.Add(currentPart.ToString());
return args;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.