【问题标题】:How to combine List elements in between certain elements如何在某些元素之间组合列表元素
【发布时间】:2019-03-05 18:46:46
【问题描述】:

我有一个输入字符串://CommandName "Hello this World" (5, 4, 3)

我使用拆分从这个输入中获取所有条目,并将其全部存储在列表中。

List<String> s = input.Split().ToList();

如何组合以'"'开头和结尾的元素之间的所有元素?

矢量坐标也一样吗?例如(2, 5, 8)。 因此,组合以( 开头和以) 结尾的元素之间的所有元素。

我应该为此使用正则表达式吗?

【问题讨论】:

  • 请标记一种语言。
  • 嘿,对不起,我正在使用 c#。我更新了指定它的问题
  • 在字符串参数"Hello (test) example" 中使用括号是否合法(我认为是这样),在括号("5", "6", "7") 中使用括号是否合法?
  • 我会为此选择数组。您可以遍历字符并将它们收集/组合到另一个数组或列表中。这使您能够控制字符的索引。
  • 带有捕获组的正则表达式可能适用于此

标签: c# string parsing input split


【解决方案1】:

一个真正的带有正则表达式的基本示例:

var pattern = new Regex("([^ ]+) \"([^\"]+)\" \\(([^)]+)\\)");
var match = pattern.Match("command \"string\" (0, 1, 2)");
var command = match.Groups[1];
var text = match.Groups[2];
var location = match.Groups[3];

Console.WriteLine(command);
Console.WriteLine(text);
Console.WriteLine(location);

此示例假定您将始终具有相同数量的相同类型的参数,并且它不处理在字符串中包含引号,但它让您了解如何使用正则表达式实现这一点。

正则表达式的解释

(?<command>[^ ]+)                                  The first sequence of characters up to a space
( (?<parameter>...))*                              Zero or more parameters, separated by a space

parameter 捕获组的表达式为以下任意一种:

(?<boolean>true|false)                             A boolean literal
(?<integer>[+-]?[0-9][0-9]*)                       An integer literal
(?<float>[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)   A floating point literal
(?<string>\"[^\"]+\")                              A string literal
(?<vector>\\([^)]+\\))                             A vector literal

由于您设法为整数和浮点数添加了自己的表达式,我假设您了解每个单独的正则表达式如何匹配它们各自的部分。一旦你将所有这些表达式与中间的管道符号组合在一起,它看起来有点令人生畏。

【讨论】:

  • 谢谢!这不会真正起作用,因为输入可能不同,例如//CommandName "Some Text" 5 false (1, 2, 3)。也可能有不同的条目,如布尔值或整数或单个等等,并且所有条目的顺序都不同。所以我想知道是否有一种模式可以找到所有由空格分隔的匹配项,并且会忽略引号或括号等字符之间的空格?我不太擅长正则表达式模式。就在不久前开始研究一般的正则表达式。
  • 是的,您可以有一个模式来匹配所有不同类型的参数,并且您可以重复捕获该模式(这可以在一个正则表达式中完成)。然后在您的代码中,您必须检查它匹配的组以确定您应该如何解析它。
  • 例如"(?&lt;command&gt;[^ ]+)( (?&lt;parameter&gt;(?&lt;boolean&gt;true|false)|(?&lt;string&gt;\"[^\"]+\")|(?&lt;vector&gt;\\([^)]+\\))))*"。我已经命名了捕获组以便于访问,因此您可以调用match.Groups["command"]等而不是按索引引用。要迭代参数,foreach (var capture in match.Groups["parameter"].Captures)
  • 您的示例效果很好!谢谢 :) 我添加了更多数据类型,整数 ("(?&lt;integer&gt;[+-]?[0-9][0-9]*)") 和浮点数,但浮点数有一些问题。 "(?&lt;float&gt;[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)" 它给了我一个错误,上面写着 Unrecognized escape sequence 错误发生在模式中的这个 \. 上。作为一个正则表达式的菜鸟,我对这整件事有点困惑。这种性能明智是一个不错的选择吗?
  • 这是整个模式目前的样子:var pattern = new Regex("(?&lt;command&gt;[^ ]+)( (?&lt;parameter&gt;(?&lt;boolean&gt;true|false)|(?&lt;integer&gt;[+-]?[0-9][0-9]*)|(?&lt;float&gt;[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)|(?&lt;string&gt;\"[^\"]+\")|(?&lt;vector&gt;\\([^)]+\\))))*"); 一半看不懂的时候看起来有点吓人:p
猜你喜欢
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 2015-02-10
  • 2021-10-29
  • 2011-08-26
  • 2016-12-19
  • 1970-01-01
  • 2021-06-15
相关资源
最近更新 更多