在正则表达式c#中捕获特定的或组

本文关键字:正则表达式 | 更新日期: 2023-09-27 18:03:07

我试图解析匹配一个文件名,如xxxxSystemCheckedOut.png,其中xxx可以是文件名的任何前缀,System和Checked out是要识别的关键字。

编辑:我不清楚所有可能的文件名和他们的结果。文件名可以是

  • xxxxSystem.png产生(组1:xxxx组2:System)
  • xxxxSystemCheckedOut.png产生(组1:xxxx组2:系统组3:CheckedOut)
  • xxxxCheckedOut.png产生(组1:xxxx组2:CheckedOut)

这是我当前的正则表达式,它匹配文件名,就像我想要的,但不能让它以正确的方式分组。使用前面的例子,我希望组是这样的:

  1. xxxx
  2. 系统
  3. CheckedOut
  4. . png

(?:(['w]*)(CheckedOut|System)+('.[a-z]*)'Z)

在正则表达式c#中捕获特定的或组

[EDIT]试试吧。

模式:(.*?)(?:(System)|(CheckedOut)|(Cached))+(.png)'Z

String: xxxxTESTSystemCached.png

组:

  1. xxxxTest
  2. 系统
  3. 缓存
  4. . png
https://regex101.com/r/jE5eA4/1

UPDATE -基于对其他答案的评论:这应该适用于System/CheckedOut/Cached:

的所有组合
('w+?)(System)?(CheckedOut)?(Cached)?(.png)
https://regex101.com/r/qT2sX9/1

请注意,缺少关键字的组仍然存在,因此例如:

"abcdSystemCached.png"了:

匹配1:"abcd"
配对2:"System"
匹配3:
匹配4:"Cached"
匹配5:".png"

和"1234CheckedOutCached.png"给出:

匹配1:"abcd"
匹配2:
配对3:"CheckedOut"
匹配4:"Cached"
匹配5:".png"

这很好,因为你知道一个特定的关键字总是在某个位置,所以它就像一个标志。

来自评论:I actually need the groups separately so I know how to operate on the image, each keyword ends in different operations on the image

你真的不需要对关键字使用单独的捕获缓冲区。
如果需要匹配的关键字的相对顺序,请使用
您将使用下面的代码。即使你不需要顺序也可以是
就像这样。

 ( .*? )                       # (1)
 ( System | CheckedOut )+      # (2)
 '.png $
c#:

string fname = "xxxxSystemCheckedOutSystemSystemCheckedOutCheckedOut.png";
Regex RxFname = new Regex( @"(.*?)(System|CheckedOut)+'.png$" );
Match fnameMatch = RxFname.Match( fname );
if ( fnameMatch.Success )
{
    Console.WriteLine("Group 0 = {0}", fnameMatch.Groups[0].Value);
    Console.WriteLine("Group 1 = {0}", fnameMatch.Groups[1].Value);
    Console.WriteLine("Last Group 2 = {0}'n", fnameMatch.Groups[2].Value);
    CaptureCollection cc = fnameMatch.Groups[2].Captures;
    Console.WriteLine("Array and order of group 2 matches (collection):'n");
    for (int i = 0; i < cc.Count; i++)
    {
        Console.WriteLine("[{0}] = '{1}'", i, cc[i].Value);
    }
}
输出:

Group 0 = xxxxSystemCheckedOutSystemSystemCheckedOutCheckedOut.png
Group 1 = xxxx
Last Group 2 = CheckedOut
Array and order of group 2 matches (collection):
[0] = 'System'
[1] = 'CheckedOut'
[2] = 'System'
[3] = 'System'
[4] = 'CheckedOut'
[5] = 'CheckedOut'

我不是Regex向导,所以如果这可以缩短/整理我很想知道,但这组喜欢你想基于你给的关键字:

根据OPs对文件结构的澄清编辑

('w+?)(system)?(checkedout)?(cached)?(.png)/ig

Regex101演示

编辑:啤酒和乔恩打败了我;-)

我在某个地方读到过(不记得在哪里了),你的模式越精确,你的性能就越好。

试试这个模式

"(''w+?)(?:(System)|(CheckedOut))+(.png)"

代码示例:

List<string> fileNames = new List<string>
{
    "xxxxSystemCheckedOut.png",         // Good
    "SystemCheckedOut.png",             // Good
    "1afweiljSystemCheckedOutdgf.png",  // Bad - Garbage characters before .png
    "asdf.png",                         // Bad - No System or CheckedOut
    "xxxxxxxSystemCheckedOut.bmp",      // Bad - Wrong file extension
    "xxSystem.png",                     // Good
    "xCheckedOut.png"                   // Good
};
foreach (Match match in fileNames.Select(fileName => Regex.Match(fileName, "(''w+?)(?:(System)|(CheckedOut))+(.png)")))
{
    List<Group> matchedGroups = match.Groups.Cast<Group>().Where(group => !String.IsNullOrEmpty(group.Value)).ToList();
    if (matchedGroups.Count > 0)
    {
        matchedGroups.ForEach(Console.WriteLine);
        Console.WriteLine();
    }
}

结果:

xxxxSystemCheckedOut.png
xxxx
System
CheckedOut
.png
SystemCheckedOut.png
System
CheckedOut
.png
xxSystem.png
xx
System
.png
xCheckedOut.png
x
CheckedOut
.png