Skip to main content
 首页 » 编程设计

c#之正则表达式包括结果中应该是非捕获组的内容

2024年01月31日32sxdcgaq8080

我有以下简单测试,我试图获取 Regex 模式,以便它提取没有“.exe”后缀的可执行文件名称。

我的非捕获组设置 (?:\\.exe) 似乎不起作用,或者我误解了它的工作原理。

两者 regex101和 regexstorm.net显示相同的结果,前者确认“(?:\.exe)”是非捕获匹配。

对我做错了什么有什么想法吗?

// test variable for what i would otherwise acquire from Environment.CommandLine 
var testEcl = "\"D:\\src\\repos\\myprj\\bin\\Debug\\MyApp.exe\" /?" 
var asmName = Regex.Match(testEcl, @"[^\\]+(?:\.exe)", RegexOptions.IgnoreCase).Value; 
// expecting "MyApp" but I get "MyApp.exe" 

我已经能够通过使用定义了组名的匹配模式来提取我想要的值,如下所示,但我想了解为什么非捕获组设置方法没有按我预期的方式工作到。

// test variable for what i would otherwise acquire from Environment.CommandLine 
var testEcl = "\"D:\\src\\repos\\myprj\\bin\\Debug\\MyApp.exe\" /?" 
var asmName = Regex.Match(Environment.CommandLine, @"(?<fname>[^\\]+)(?<ext>\.exe)",  
    RegexOptions.IgnoreCase).Groups["fname"].Value; 
// get the desired "MyApp" result 

/欧克

请您参考如下方法:

(?:...) 是一个非捕获组,它匹配并仍然使用 文本。这意味着该组匹配的文本部分仍将添加到整体匹配值中。

一般,如果你想匹配某样东西而不消费,你需要使用lookarounds。因此,如果您需要匹配后跟特定字符串的内容,请使用正向先行、(?=...) 构造:

some_pattern(?=specific string) // if specific string comes immmediately after pattern 
some_pattern(?=.*specific string) // if specific string comes anywhere after pattern 

如果您之前需要匹配但“从匹配中排除”某些特定文本,请使用正面回顾:

(?<=specific string)some_pattern // if specific string comes immmediately before pattern 
(?<=specific string.*?)some_pattern // if specific string comes anywhere before pattern 

请注意 .*? 或 .* - 即带有 *、+、?、{2,} 甚至 {1,3} 量词 - 在后视模式中,正则表达式引擎并不总是支持,但是,C# . NET 正则表达式引擎幸运地支持它们。它们还受到 Python PyPi regex 模块、Vim、JGSoft 软件以及现在符合 ECMAScript 2018 的 JavaScript 环境的支持。

在这种情况下,您可以捕获您需要获取的内容并仅匹配上下文而不捕获:

var testEcl = "\"D:\\src\\repos\\myprj\\bin\\Debug\\MyApp.exe\" /?"; 
var asmName = string.Empty;  
var m = Regex.Match(testEcl, @"([^\\]+)\.exe", RegexOptions.IgnoreCase); 
if (m.Success) 
{ 
    asmName = m.Groups[1].Value; 
} 
Console.WriteLine(asmName); 

参见 C# demo

详情

  • ([^\\]+) - 捕获第 1 组:\
  • 以外的一个或多个字符
  • \. - 文字点
  • exe - 文字 exe 子字符串。

因为我们只对捕获组 #1 的内容感兴趣,所以我们捕获 m.Groups[1].Value,而不是整个 m.Value(包含.exe).