在正则表达式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)
这是我当前的正则表达式,它匹配文件名,就像我想要的,但不能让它以正确的方式分组。使用前面的例子,我希望组是这样的:
- xxxx 系统
- CheckedOut
- . png
(?:(['w]*)(CheckedOut|System)+('.[a-z]*)'Z)
[EDIT]试试吧。
模式:(.*?)(?:(System)|(CheckedOut)|(Cached))+(.png)'Z
String: xxxxTESTSystemCached.png
组:
- xxxxTest 系统缓存
- . png
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