C# 提取不带多个模式的可变长度文本的多个实例

C# 提取不带多个模式的可变长度文本的多个实例,c#,.net,regex,C#,.net,Regex,需要从以下数据.xxx[val1,val2,val3]中提取val1、val2和val3的值 如果使用此模式,则可以提取数据,但当数据字符串发生变化时,无法获取所有数据 以这些变量为例 .xxx[val1] 或.xxx[val1,val2,val3,val4,val5] 或者最后是.xxx[{1-N},] 哪种正则表达式模式可以在作为示例提供的所有数据集上获得结果?一种更简单的方法是匹配[]中的所有内容,然后分割匹配 text.match(/\[(.*)\]/)[1].split(", ");

需要从以下数据
.xxx[val1,val2,val3]
中提取
val1
val2
val3
的值

如果使用此模式,则可以提取数据,但当数据字符串发生变化时,无法获取所有数据

以这些变量为例

.xxx[val1]
.xxx[val1,val2,val3,val4,val5]
或者最后是
.xxx[{1-N},]


哪种正则表达式模式可以在作为示例提供的所有数据集上获得结果?

一种更简单的方法是匹配
[]
中的所有内容,然后分割匹配

text.match(/\[(.*)\]/)[1].split(", "); //And now you have an array with var1,var2..etc

这里有一个javascript示例,我不做c,所以不想把它搞砸:)

您可以在第一步中捕获
@“\[(.*?)\]”“
,然后在
上拆分,这肯定比使用regexp执行相同操作快得多

尽管组在重复时会覆盖其值,但它会将整个捕获堆栈存储为捕获集合,由Group.captures属性中的每个组返回

Captures属性的真正用途是将量词应用于捕获组,以便该组在单个正则表达式中捕获多个子字符串。在本例中,Group对象包含有关上次捕获的子字符串的信息,而Captures属性包含有关该组捕获的所有子字符串的信息

然后,您可以简单地使用此模式:

\[(?:([^,\]]+),?\s*)+\]
代码:

string pattern = @"\[(?:([^,\]]+),?\s*)+\]";
var re = new Regex( pattern);
var text = @".xxx[val1, val2, val3]";


MatchCollection matches = re.Matches(text);
for (int mnum = 0; mnum < matches.Count; mnum++)
{   //loop matches
    Match match = matches[mnum];
    Console.WriteLine("Match #{0} - Value: {1}", mnum + 1, match.Value);
    int captureCtr = 0;
    foreach (Capture capture in match.Groups[1].Captures)
    {  //loop captures for the 1st Group
       Console.WriteLine("      Capture {0}: {1}", 
                         captureCtr, capture.Value);
       captureCtr += 1;                  
    }
}
Match #1 - Value: [val1, val2, val3]
      Capture 0: val1
      Capture 1: val2
      Capture 2: val3
正确的模式是什么

最佳实践不是匹配未知,而是根据已知来设计图案。在类似的实践中,不盲目地使用
*
(零或更多)进行回溯匹配可能会非常慢;为什么在不需要的时候增加复杂性

坦率地说,人们应该更喜欢
+
一个或多个用法,而不是
*
零个或多个用法,当特定项目可能不出现时,应该真正使用这些用法

字符串可以变化

从您的示例中可以看出,如果我们像编译器一样思考,则标记由
或结尾
]
分隔。因此,让我们用这些知识(知识)开发一个模式

最好的捕获方法是消费,直到找到已知的。使用not集合的
[^]
模式是最好的;表示匹配此集合中的字符而不是。然后加上总量词
+
,表示一个或多个。有效地替换了旧模式中的
*
,但相反


var data=“.xxx[val1,val2,val3,val4,val5]”;
变量模式=@“
[^[]+#消费任何不是大括号的东西
#但不匹配,(.xxx是第一个主播)
\[#开始工作
(#比赛开始捕获
(?[^\s,\]]+)#命名的匹配分组称为'Token',其中一个或多个
#除空格外的任何内容都会捕获逗号或大括号。
[\s,\]]+#使用令牌的`、`或空格或最后一个括号。
)+#结束匹配捕获,一个或多个
]#结束支撑。”
;
//IgnorePatternWhitespace允许我们对模式进行注释,
//不影响解析器处理。
Regex.Match(数据、模式、RegexOptions.IgnorePatternWhitespace)
.组[“令牌”]
.捕获
第()类
.选择(cp=>cp.Value);
结果


如果您不能定义模式,那么您将很难创建一个合适的正则表达式来匹配它们。很多地方都被“弦可以变”所覆盖。事实上,Ausgezeichnet的问题。我已经为一个说英语的听众改写了它,但我自己很清楚你在问什么。哇!谢谢你的回答:)
var data = ".xxx[val1, val2, val3, val4, val5]";

var pattern = @"
[^[]+                     # Consume anything that is *not* a brace
                          #  but don't match it , (.xxx is the first anchor)
\[                        # Starting brace consumed
(                       # Start of match captures
   (?<Token>[^\s,\]]+)    # Named Match grouping called `Token` where one or more
                          # of anything not a space, comma or end brace is captured.
   [\s,\]]+               # Consume the token's `,` or space or final bracket.
)+                      # End match captures, one or more
]                         # Ending brace."
;

// IgnorePatternWhitespace allows us to comment the pattern, 
// does not affect parser processing.

Regex.Match(data, pattern, RegexOptions.IgnorePatternWhitespace)
     .Groups["Token"]
     .Captures
     .OfType<Capture>()
     .Select(cp => cp.Value);