正则表达式(.NET方言):捕获组的奇怪行为

时间:2011-01-24 14:48:42

标签: .net regex

我被困住了。为什么此代码中的组path的值 2/3/4 ,而不是 1/2/3/4 1 / 去了哪里?表达式的哪一部分匹配 1 /

var re = new Regex(@"^-/?(?'folder'((?'path'.+?)/)??[^/]*)/?$");
var m = re.Match("-1/2/3/4/5");
m.Groups["folder"].Value.Dump("Folder");
m.Groups["path"].Value.Dump("Path");

3 个答案:

答案 0 :(得分:5)

看起来这是.NET 3.5和4.0之间的行为差​​异。这是一个完整的计划:

using System;
using System.Text.RegularExpressions;

class Test
{
    static void Main()
    {
        var re = new Regex(@"^-/?(?'folder'((?'path'.+?)/)??[^/]*)/?$");
        var m = re.Match("-1/2/3/4/5");
        Console.WriteLine("Folder: " + m.Groups["folder"].Value);
        Console.WriteLine("Path: " + m.Groups["path"].Value);
    }
}

在.NET 3.5下编译并运行:

Folder: 1/2/3/4/5
Path: 2/3/4

在.NET 4下编译并运行:

Folder: 1/2/3/4/5
Path: 1/2/3/4

我不知道为什么行为应该有所不同......

编辑:我对此进行了进一步调查......在.NET 3.5下,该组包含两个捕获:“1”和“2/3/4”。在.NET 4下,它是单个捕获“1/2/3/4”。

答案 1 :(得分:0)

Path组有两个捕获,"1""2/3/4"(我不太明白,因为你是说零或一个没有提供一个该组的量词[并为该周围的编号捕获组说零或一个])

答案 2 :(得分:0)

关于您的模式的奇怪之处在于在路径组之后使用??。你为什么不只使用??此元字符使前面的项目成为可选项,如果可能,它将在匹配项中排除。

@"^-/?(?'folder'((?'path'.+?)/)??[^/]*)/?$"
                                ^
                 remove this  __|

新模式:@"^-/?(?'folder'((?'path'.+?)/)?[^/]*)/?$"

在.NET 3.5下编译,返回所需的结果。在.NET 4.0下,任一模式都有效,这表明行为的差异为Jon pointed out