C#中奇怪的正则表达式行为

时间:2015-10-07 12:23:40

标签: c# regex

我做了以下正则表达式:

y

适用于任何正则表达式测试人员。然而,当我在C#中尝试它时,它有点奇怪。假设我将这3个字符串与它进行比较:

(?<=^PR)(?:[gpr])?([A-Z]{2,3})(?:vB)?(?=\d{4}$)

正则表达式测试器匹配以下内容:

PRPCP2008, PRrSV2012 and PRBP2006

这就是我想要发生的事情。我只关心“PR”和任何4位数年份之间的2或3个大写字母。我确实寻找小写字符,但不想匹配它们。现在,当我在C#中使用相同的正则表达式时,我得到不同的匹配:

PCP, SV and BP

PCP和BP仍然相同。但现在它还包括小写的'r'。有没有理由在c#中发生这种情况?或者我只是偶然发现了一个错误的正则表达式测试员?

如果您想测试正则表达式,我使用了以下正则表达式测试器:http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx

编辑: 好吧,代码

PCP, rSV and BP

2 个答案:

答案 0 :(得分:1)

您正在查看匹配值,但您需要一个组。

var rx = new Regex(@"(?<=^PR)(?:[gpr])?(?'interest'[A-Z]{2,3})(?:vB)?(?=\d{4}$)", RegexOptions.None);

var items = new[] { "PRPCP2008", "PRrSV2012", "PRBP2006", "Foo"};

var results = items.Select(i => new { i, isMatch = rx.IsMatch(i), value = rx.Matches(i).Cast<Match>().Select(m => m.Groups["interest"].Value).FirstOrDefault()});

结果:

PRPCP2008 True PCP 
PRrSV2012 True SV 
PRBP2006 True BP 
Foo False null 

这就是我总是在表达式中使用显式命名组的原因。

答案 1 :(得分:0)

从我看到的,你需要匹配多个子串与1个正则表达式。然后,您需要取消锚定模式(即删除^$):

(?<=PR)(?:[gpr])?([A-Z]{2,3})(?:vB)?(?=\d{4})

在C#中:

var reg = new Regex(@"(?<=PR)(?:[gpr])?([A-Z]{2,3})(?:vB)?(?=\d{4})");
var matches = reg.Matches(str).Cast<Match>().Select(p => p.Value).ToList();

然后,你将有3场比赛。

请参阅regex demo

enter image description here

<强>更新

您只需使用.Groups[1].Value访问SV中的PRrSV2012,请参阅demo

string regexPattern = @"(?<=^PR)(?:[gpr])?([A-Z]{2,3})(?:vB)?(?=\d{4}$)";
Regex regex = new Regex(regexPattern , RegexOptions.None);
Match match = regex.Match("PRrSV2012");
Console.WriteLine(match.Groups[1].Value);
//                      ^^^^^^^^^

请参阅IDEONE demo

MSDN中未直接声明Regex.Match对象包含捕获组,但暗示Match.Value包含整个匹配的文本。捕获组是其中的一部分,因此,应在找到匹配后访问。