正则表达式分组划分问题

时间:2018-10-19 07:18:39

标签: javascript asp.net regex

我遇到了这个问题... 我有一个必须确认的字符串,用户可以使用带正负号的分隔符(最大百分数为5)插入百分比的串联:

+33.22+10.22+11.22+4.43+4.43

第一个符号是可选的,因此先前的输入也应写为:

33.22+10.22+11.22+4.43+4.43

我写了这个正则表达式:

^(([+-]?\d{1,2}\.\d{1,2})|([+-]?\d{1,3}))(([+-]\d{1,2}\.\d{1,2})|([+-]\d{1,3})){0,4}$

它在我收到一场比赛时起作用

enter image description here

问题(如图所示)是我也希望该组,并且输入的内部部分总是被视为一个组(+ 10.22 + 11.22 + 4.43) 我不想重复这样的原子表达式:

^(([+-]?\d{1,2}\.\d{1,2})|([+-]?\d{1,3}))(([+-]\d{1,2}\.\d{1,2})|([+-]\d{1,3}))(([+-]\d{1,2}\.\d{1,2})|([+-]\d{1,3}))(([+-]\d{1,2}\.\d{1,2})|([+-]\d{1,3}))(([+-]\d{1,2}\.\d{1,2})|([+-]\d{1,3}))$

但是我想使用量词,因为我有一些页面使用了5%的其他6%

谢谢大家!!!!!!!

1 个答案:

答案 0 :(得分:3)

您无法捕获repeated capturing grou p的所有迭代。

您可以在JS正则表达式中分两个步骤进行操作:1)测试有效性,2)提取所有匹配项(如果有效)。

if (/^(?:[+-]?(?:\d{1,2}\.\d{1,2}|\d{1,3})\b){1,5}$/.test(s)) {
    return s.match(/[+-]?\d+(?:\.\d+)?/g); 
}

详细信息

  • ^-字符串的开头
  • (?:[+-]?(?:\d{1,2}\.\d{1,2}|\d{1,3})\b){1,5}-重复1到5次
    • [+-]?-可选的+-
    • (?:\d{1,2}\.\d{1,2}|\d{1,3})-与任何一个非捕获组匹配
      • \d{1,2}\.\d{1,2}-1或2位数字,.和1或2位数字
      • |-或
      • \d{1,3}-1、2或3位数字
    • \b-单词边界
  • $-字符串的结尾。

.match(/[+-]?\d+(?:\.\d+)?/g提取- / +之后的所有子字符串-1个以上的数字-可选的.和1个以上的数字模式,来自经过验证的字符串。

演示:

var s = "+33.22+10.22+11.22+4.43+4.43";
if (/^(?:[+-]?(?:\d{1,2}\.\d{1,2}|\d{1,3})\b){1,5}$/.test(s)) {
    console.log(s.match(/[+-]?\d+(?:\.\d+)?/g)); 
}

但是,在C#中,您可以通过任何CaptureCollection中的Group访问所有捕获的子字符串:

var s = "+33.22+10.22+11.22+4.43+4.43";
var m = Regex.Match(s, @"^([+-]?(?:\d{1,2}\.\d{1,2}|\d{1,3})\b){1,5}$");
if (m.Success) 
{
    var captures = m.Groups[1].Captures.Cast<Capture>().Select(p => p.Value).ToList();
    foreach (var x in captures)
        Console.WriteLine(x);
}
else
{
    Console.WriteLine("No match!");
}

请参见C# demo。输出:

+33.22
+10.22
+11.22
+4.43
+4.43

请注意(...)在.NET模式中的位置。