C# 正则表达式:重复捕获组
我必须从ASCII文本文件中解析一些表。以下是部分样本: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
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})