2016-02-24 54 views
1

我想解析给定的字符串,这是一种用/分隔的路径。我需要编写正则表达式,将路径中的每个段匹配到相应的正则表达式组。与可选匹配组的正则表达式

实施例1:

输入:

/EAN/SomeBrand/appliances/refrigerators/RF444

输出:

Group: producer, Value: SomeBrand Group: category, Value: appliances Group: subcategory, Value: refrigerators Group: product, Value: RF4441

实施例2:

输入:

/EAN/SomeBrand/appliances

输出:

Group: producer, Value: SomeBrand Group: category, Value: appliances Group: subcategory, Value: Group: product, Value:

我尝试下面的代码,它工作正常时,路径是满的(像在第一〔实施例),但未能找到当输入字符串不偏不倚时(如例2)。

static void Main() 
{ 
    var pattern = @"^" + @"/EAN" 
       + @"/" + @"(?<producer>.+)" 
       + @"/" + @"(?<category>.+)" 
       + @"/" + @"(?<subcategory>.+)" 
       + @"/" + @"(?<product>.+)?" 
       + @"$"; 

    var rgx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); 
    var result = rgx.Match(@"/EAN/SomeBrand/appliances/refrigerators/RF444"); 

    foreach (string groupName in rgx.GetGroupNames()) 
    { 
    Console.WriteLine(
     "Group: {0}, Value: {1}", 
     groupName, 
     result.Groups[groupName].Value); 
    } 


    Console.ReadLine(); 
} 

任何建议是值得欢迎的。不幸的是,我不能简单地拆分字符串,因为我使用的框架期望正则表达式对象。

+0

这是否意味着您的所有零件(包括'producer'和'category')都是可选的? –

回答

1

尝试

var pattern = @"^" + @"/EAN" 
    + @"(?:/" + @"(?<producer>[^/]+))?" 
    + @"(?:/" + @"(?<category>[^/]+))?" 
    + @"(?:/" + @"(?<subcategory>[^/]+))?" 
    + @"(?:/" + @"(?<product>[^/]+))?"; 

注意我如何与[^/]取代.,因为要使用/拆分字符串。请注意,即使每个子部分使用可选的量词(?

2

您可以使用可选组(...)?与否定的字符类[^/]+更换.+贪婪点匹配模式:

^/EAN/(?<producer>[^/]+)/(?<category>[^/]+)(/(?<subcategory>[^/]+))?(/(?<product>[^/]+))?$ 
             ^     ^^^     ^^ 

regex demo

这就是你需要声明你的正则表达式在C#代码:

var pattern = @"^" + @"/EAN" 
      + @"/(?<producer>[^/]+)" 
      + @"/(?<category>[^/]+)" 
      + @"(/(?<subcategory>[^/]+))?" 
      + @"(/(?<product>[^/]+))?" 
      + @"$"; 

var rgx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); 

注意我正在使用常规捕获组作为可选项,但RegexOptions.ExplicitCapture标志将所有非命名捕获组转换为未捕获,因此它们不出现在Match.Groups之间。因此,我们始终只有5个组,甚至没有使用非捕获可选组(?:...)?