我有一些这种格式的文字数据:
MI
00
3
MD
1
0.0000
MD
2
0.0000
MD
3
0.0000
可以重复此块,并且MD的数量是可变的(但总是> = 1),并且需要为每个块捕获以下数值。
我有一个匹配每个MI的每个MD的正则表达式,但它只捕获最后一个MD。是否有可能在不事先知道有多少MD的情况下捕获每个MD?
编辑:根据请求... 正则表达式在下面;我的问题的重要部分仍然是“我可以捕获每一个MD集吗?”
MI\r\d\d\r(\d)\r[\s\w]{6}\r(MD\r[\s\d]{2}\r[\s\d\.\-]*\r)+
我选择的语言是C#,但我会用任何语言回答,因为它至少会给我一个开始。
MD是从90年代初开始的硫检测器中的数据点。
答案 0 :(得分:3)
每个Match都有一个Groups集合。在您的情况下,匹配[0] .Groups [1]将匹配MD记录,如“MD \ n1 \ n0.0000MD \ n2 \ n0.0000MD \ n3 \ n0.0000”。
每个组都有Captures collection,您可以迭代查找所有MD实例。这将为每个MD提供一个字符串,因此Matches [0] .Groups [1] .Captures [0]将为“MD \ n1 \ n0.0000”。
编辑:虽然您已经接受了答案,但这是一种解决所有问题的方法:
string pat = @"MI[\r\n]*(?<MI1>\d\d)[\r\n]*(?<MI2>\d+)[\r\n]*" +
@"(MD[\r\n]*(?<MD1>\d+)*[\r\n]*(?<MD2>[\d\.\-]+)+[\r\n]*)*";
var r = new Regex(pat);
foreach (Match match in r.Matches(text))
{
Console.WriteLine("MI v1:{0} v2:{1}",
match.Groups["MI1"], match.Groups["MI2"]);
if (match.Groups.Count > 2)
for (var i = 0; i < match.Groups["MD1"].Captures.Count; i++)
Console.WriteLine(" MD v1:{0} v2:{1}",
match.Groups["MD1"].Captures[i],
match.Groups["MD2"].Captures[i]);
}
这是我使用的测试文本:
MI
00
3
MD
1
0.1000
MD
2
0.2000
MD
3
0.3000
MI
12
5
MI
24
5
MD
1
0.1000
输出结果为:
MI v1:00 v2:3
MD v1:1 v2:0.1000
MD v1:2 v2:0.2000
MD v1:3 v2:0.3000
MI v1:12 v2:5
MI v1:24 v2:5
MD v1:1 v2:0.1000
答案 1 :(得分:2)
这是可能的,但它需要不止一次通过数据。正则表达式组每次匹配只能容纳一个信息块。因此,您可以拥有一个MD组并查找所有MD匹配或一个包含MD组的MI组,并且可以找到所有MI匹配...但MD组不会被分离出来。
一种解决方案是嵌套的正则表达式调用,第一个解决方案是找到每个MI组,第二个解决方案是找到MI组中的每个MD组。
答案 2 :(得分:0)
我认为这样做会。至少它可以使用Perl与RegexBuddy一起使用。
MD[^MI]*
数据刚从上面重复。
编辑: 这似乎捕获了所有MD和初始MI在它自己的小块中。
MI([^MI]*(MD[^MI]*)*)
答案 3 :(得分:0)
我不是C#的专家,但在Java中,你想要改变(MD ...)+到((MD ...)+)。这样,您可以使用外部括号来捕获所有MD。
答案 4 :(得分:0)