C# 正则表达式:重复捕获组

C# 正则表达式:重复捕获组,c#,.net,regex,C#,.net,Regex,我必须从ASCII文本文件中解析一些表。以下是部分样本: QSMDRYCELL 11.00 11.10 11.00 11.00 -.90 11 11000 1.212 RECKITTBEN 192.50 209.00 192.50 201.80 5.21 34 2850 5.707 RUPALIINS 150.00 159.00 150.00 156.25 6.29 4

我必须从ASCII文本文件中解析一些表。以下是部分样本:

QSMDRYCELL   11.00   11.10   11.00   11.00    -.90      11     11000     1.212
RECKITTBEN  192.50  209.00  192.50  201.80    5.21      34      2850     5.707
RUPALIINS   150.00  159.00  150.00  156.25    6.29       4        80      .125
SALAMCRST   164.00  164.75  163.00  163.25    -.45      80      8250    13.505
SINGERBD    779.75  779.75  770.00  773.00    -.89       8        95      .735
SONARBAINS   68.00   69.00   67.50   68.00     .74      11      3050     2.077
该表由1列文本和8列浮点数组成。我想通过正则表达式捕捉每一列

我对正则表达式很陌生。下面是我提出的错误正则表达式模式:

(\S+)\s+(\s+[\d\.\-]+){8}
但是模式只捕获第一列和最后一列。RegexBuddy还发出以下警告:

你重复了捕获组 它本身该小组将只捕获 最后一次迭代。放枪 在重复的组周围分组 捕获所有迭代

我查阅了他们的帮助文件,但我不知道如何解决这个问题


如何分别捕获每个列?

不幸的是,您需要重复
(…)
8次才能分别获取每个列

^(\S+)\s+([-.\d]+)\s+([-.\d]+)\s+([-.\d]+)\s+([-.\d]+)\s+([-.\d]+)\s+([-.\d]+)\s+([-.\d]+)\s+([-.\d]+)$
如果可以编写代码,可以首先将这些数字列作为一个整体进行匹配

>>> rx1 = re.compile(r'^(\S+)\s+((?:[-.\d]+\s+){7}[-.\d]+)$', re.M)
>>> allres = rx1.findall(theAsciiText)
然后按空格分割列

>>> [[p] + q.split() for p, q in allres]
在C#(修改自):


如果您想知道出现警告的原因,这是因为您的捕获组匹配多次(如您指定的,为8次),但捕获变量只能有一个值。它被分配最后一个匹配的值

如中所述,使用正则表达式通常不可能检索这些多个匹配项,尽管.NET和Perl 6对此有一些支持

警告提示您可以在整个集合周围放置另一组,如下所示:

(\S+)\s+((\s+[\d\.\-]+){8})

然后,您将能够看到所有列,但它们当然不会分开。因为通常不可能单独捕获它们,所以更常见的目的是捕获所有这些,警告有助于提醒您这一点。

Kenny,感谢您的及时回复!实际上我现在正在使用这种模式。但我想知道是否有更好的解决方案使用重复捕获组。@Brass:我所知道的不是重复捕获组。如果你不想用一次性的方法做得过火,正则表达式通常工作得最好。肯尼特:谢谢!你的解决方案是有效的——我也在做类似的事情,虽然不那么优雅。NET的特殊之处在于它保留了中间捕获!看看蒂姆的答案,你用的是哪种语言?在.NET中很容易。@Tim:是的,我打算用C语言编写程序。但目前,我正在用Python制作原型。另请参见:它可以通过组捕获进行检索。看看谢谢你的提醒。我正在查看Group.Captures属性。
Captures
是一个很好的功能,但在这里似乎有些过分了。为什么不在空白处分开每一行呢?即使您使用正则表达式来验证行的格式,工作仍然更少。
Matched text: QSMDRYCELL   11.00   11.10   11.00   11.00    -.90      11     11000     1.212
...
    Group 2:      1.212
         Capture 0:  11.00
         Capture 1:    11.10
         Capture 2:    11.00
...etc.
(\S+)\s+((\s+[\d\.\-]+){8})