带有可选匹配组的正则表达式
Posted
技术标签:
【中文标题】带有可选匹配组的正则表达式【英文标题】:Regex with optional matching groups 【发布时间】:2016-06-06 22:51:43 【问题描述】:我正在尝试解析给定的字符串,它是一种用/
分隔的路径。我需要编写将路径中的每个段匹配到相应正则表达式组的正则表达式。
示例 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();
欢迎提出任何建议。不幸的是,我不能简单地拆分字符串,因为我使用的框架需要正则表达式对象。
【问题讨论】:
这是否意味着您的所有部分(包括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 个组。
【讨论】:
以上是关于带有可选匹配组的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章