C# 为什么这个正则表达式不能生成数字的组/捕获? Regex regexObj=新的Regex( @“([A-Za-z\][A-Za-z\[0-9]*)(:)([-+*%])?(\d*\.?\d*)?)*” ,RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace); var subjectString=“a:123+456;b:456;”; Match matchResults=regexObj.Match(subjectString); while(matchResults.Success){ 对于(int i=1;i,因为允许它将“作为一个有效的实现” \d*/COD>,您的捕获在出现次数之前完成。< / P>

C# 为什么这个正则表达式不能生成数字的组/捕获? Regex regexObj=新的Regex( @“([A-Za-z\][A-Za-z\[0-9]*)(:)([-+*%])?(\d*\.?\d*)?)*” ,RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace); var subjectString=“a:123+456;b:456;”; Match matchResults=regexObj.Match(subjectString); while(matchResults.Success){ 对于(int i=1;i,因为允许它将“作为一个有效的实现” \d*/COD>,您的捕获在出现次数之前完成。< / P>,c#,regex,C#,Regex,输出: st:0,len:2,val:.a st:2,len:1,val: st:6,len:0,val: ST:6,Le: 0,Val:< P>,因为允许它将“作为一个有效的实现” \d*/COD>,您的捕获在出现次数之前完成。< / P> 您应该至少指定一位数字为必填(+),而不是可选(*),以使其开始捕获组 要澄清的是,当编译正则表达式时没有错误,但没有捕获特定组的任何内容,这并不意味着匹配不成功 这意味着这场比赛是成功的,尽管它捕获了任何东西。这意味着你是故意让它越过那群人 例如,在您

输出:

st:0,len:2,val:.a

st:2,len:1,val:

st:6,len:0,val:


ST:6,Le: 0,Val:

< P>,因为允许它将“作为一个有效的实现”<代码> \d*/COD>,您的捕获在出现次数之前完成。< / P> 您应该至少指定一位数字为必填(+),而不是可选(*),以使其开始捕获组

要澄清的是,当编译正则表达式时没有错误,但没有捕获特定组的任何内容,这并不意味着匹配不成功

这意味着这场比赛是成功的,尽管它捕获了任何东西。这意味着你是故意让它越过那群人

例如,在您自己的正则表达式中:
([-+*%])?(\d*\.?\d*)?)*
您的意思是:我期望一些可选符号后跟一个十进制数,尽管这也是可选的。如果什么也没找到,那也没关系,不过,亲爱的RegExp引擎,请不要自找麻烦,因为我不在乎是否发生了这种情况

让我们进一步细分:

  • \d*\.\d*
    表示任何数字(包括零)中间有点的东西。因此,
    0.
    .123
    ,以及
    2.1
    ,都是有效的匹配项
  • 通过将该选项设置为可选,您的意思是即使是点也不是必需的,因此,
    (\d*.\d*)?
    将匹配
    (空字符串)
  • 通过编写
    ([-+*%])?(\d*\.?\d*)?
    您的意思是,如果在上面匹配的字符串之前发生任何事情,它必须是四个指示符号之一。但是,您并不要求它必须发生(因为
    )。此外,由于上面的组可以匹配空字符串,如果引擎没有成功地将字符串匹配到任何有用的内容,则指示的四个符号中的任何一个的存在将意味着该组仍然是成功的匹配。全部,包括数字
  • 现在,通过将前面的定义分组为
    ([-+*%])?(\d*\.?\d*)?)*
    ,您甚至可以将其设置为可选的,基本上告诉正则表达式引擎,如果它不在这个定义的开头寻找答案,就可以了
那么,你应该如何进行?您应该在什么时候将组设置为可选组?您应该谨慎地将组设置为可选,要知道,如果引擎无法将任何内容匹配到此组,则该语句仍然有效,并且您不关心此值

另外,作为旁注,您不应该只捕获所有内容。只捕获对您而言至关重要的值,因为引擎将为内存中您请求的任何组保留
(开始,长度)
对,这将降低性能。使用非捕获组指示器
(?:)
代替正常分组
()
,这将允许您分组和更高级别的控制,同时保留内存

捕获组的另一个用途是,当您希望引用正则表达式中的匹配内容时:

        Regex regexObj = new Regex(
        @"([A-Za-z_][A-Za-z_0-9]*)(:)(([-+*%])?(\d*\.?\d*)?)*"
           , RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);

        var subjectString = "a:123+456;b:456;";
        Match matchResults = regexObj.Match(subjectString);
        while (matchResults.Success) {
            for (int i = 1; i < matchResults.Groups.Count; i++) {
                Group grp = matchResults.Groups[i];
                if (grp.Success) {
                    Console.WriteLine("st:" + grp.Index + ", len:" + grp.Length + ", val:" + grp.Value);
                }
            }
            matchResults = matchResults.NextMatch();
        }
*?

它将捕获一个XML标记及其匹配的结束标记。还请注意,上面的示例仅用于演示,一般来说,使用正则表达式解析任何类型的分层文档(除了最普通的正则表达式)都是一个大写B、大写I的坏主意。

非常感谢。更改了一个字符,现在可以使用了。顺便说一句:当你得到一个长度为零的组时,我认为这只是意味着该可选组没有成功匹配?我只是用信息和细节更新了答案,这将给你(可能)更多的洞察力,并在这个评论中回答你的问题。
<(\w+)>.*?</\1>