使用空格和引号解析字符串(保留引号)

如果我有这样的string

 create myclass "56, 'for the better or worse', 54.781" 

如何解析它,结果将是三个字符串“单词”,其中包含以下内容:

 [0] create [1] myclass [2] "56, 'for the better or worse', 54.781" 

编辑2:请注意保留引号

起初,我尝试使用string.Split(' ') ,但我注意到它会使第三个string被破坏为少数其他字符串。

我尝试使用其count参数为3来限制Split结果以解决此问题。 对于这种情况是否可以,但是当给定的字符串是

 create myclass false "56, 'for the better or worse', 54.781" //or create myclass "56, 'for the better or worse', 54.781" false 

然后拆分失败,因为最后两个单词将合并。

我还创建了类似ReadInBetweenSameDepth东西来获取引号之间的string

这是我的ReadInBetweenSameDepth方法

 //Examples: //[1] (2 + 1) * (5 + 6) will return 2 + 1 //[2] (2 * (5 + 6) + 1) will return 2 * (5 + 6) + 1 public static string ReadInBetweenSameDepth(string str, char delimiterStart, char delimiterEnd) { if (delimiterStart == delimiterEnd || string.IsNullOrWhiteSpace(str) || str.Length <= 2) return null; int delimiterStartFound = 0; int delimiterEndFound = 0; int posStart = -1; for (int i = 0; i = str.Length - 2) //delimiter start is found in any of the last two characters return null; //it means, there isn't anything in between the two if (delimiterStartFound == 0) //first time posStart = i + 1; //assign the starting position only the first time... delimiterStartFound++; //increase the number of delimiter start count to get the same depth } if (str[i] == delimiterEnd) { delimiterEndFound++; if (delimiterStartFound == delimiterEndFound && i - posStart > 0) return str.Substring(posStart, i - posStart); //only successful if both delimiters are found in the same depth } } return null; } 

但是虽然这个函数正常工作,但我发现很难将结果与string.Split结合起来,以便string.Split需要进行正确的解析。

编辑2:在我糟糕的解决方案中,我需要稍后重新添加引号

有没有更好的方法来做到这一点? 如果我们使用正则Regex ,我们该怎么做?

编辑:

老实说,我不知道这个问题可以像CSV格式的文本一样解决。 我也不知道这个问题不一定是由Regex解决的(因此我将其标记为这样)。 我真诚地向那些认为这是重复post的人道歉。

编辑2:

在对我的项目进行更多工作之后,我意识到我的问题出了问题(也就是说,我没有包含引号) – 我向以前最好的回答者Tim Schmelter先生道歉 。 然后在查看了欺骗链接之后,我注意到它也没有为此提供答案。

正则表达式演示

 (\w+|"[^"]*") 

获取第一个捕获组中的匹配项。

  1. \w+ :匹配字母数字字符并下划一次或多次
  2. "[^"]*" :匹配用双引号括起来的任何内容
  3. | :正则表达式中的OR条件

你可以这样拆分

 \s(?=(?:[^"]*"[^"]*")*[^"]*$) 

见演示。

https://regex101.com/r/fM9lY3/60

 string strRegex = @"\s(?=(?:[^""]*""[^""]*"")*[^""]*$)"; Regex myRegex = new Regex(strRegex, RegexOptions.Multiline); string strTargetString = @"create myclass ""56, 'for the better or worse', 54.781"""; return myRegex.Split(strTargetString); 

我会使用一个真正的csv-parser来完成这项任务。 框架中唯一可用的是VisualBasic命名空间中的TextFieldParser -class :

 string str = "create myclass \"56, 'for the better or worse', 54.781\""; var allLineFields = new List(); using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(new StringReader(str))) { parser.Delimiters = new string[] { " " }; parser.HasFieldsEnclosedInQuotes = true; // important string[] lineFields; while ((lineFields = parser.ReadFields()) != null) { allLineFields.Add(lineFields); } } 

结果:

在此处输入图像描述

但是还有其他像这样或者这样的人 。