首页 > 解决方案 > 除非在单引号或双引号中,否则如何用空格分隔字符串

问题描述

我意识到这个问题已经在这里被问过很多次了。我已经查看并尝试了许多答案,但没有一个对我有用。

我正在使用可以接受命令行参数的 C# 创建一个应用程序。例如

  1. Start -p:SomeNameValue -h
  2. DisplayMessage -m:Hello
  3. DisplayMessage -m:'Hello World'
  4. DisplayMessage -m:"Hello World"

我的 args 以单个字符串的形式出现。我需要用空格分隔,除非有单引号或双引号。所以上面的结果会是

  1. Start -p:SomeNameValue -h
  2. DisplayMessage -m:Hello
  3. DisplayMessage -m:'Hello World'
  4. 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 分成块。

标签: c#.netregexcommand-line-argumentsquoting

解决方案


这是一个简单的演示程序,我认为它通过解析字符串完全符合您的要求。

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();
    }
}

该程序将产生以下输出:

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"'


推荐阅读