如何在正则表达式列表中找到与我的输入匹配的第一个正则表达式
本文关键字:正则表达式 输入 我的 第一个 列表 | 更新日期: 2023-09-27 18:20:11
有其他方法可以编写以下内容吗?
string input;
var match = Regex.Match(input, @"Type1");
if (!match.Success)
{
match = Regex.Match(input, @"Type2");
}
if (!match.Success)
{
match = Regex.Match(input, @"Type3");
}
基本上,我想让我的字符串穿过一个表情的gammut,看看哪一个能粘住。
var patterns = new[] { "Type1", "Type2", "Type3" };
Match match;
foreach (string pattern in patterns)
{
match = Regex.Match(input, pattern);
if (match.Success)
break;
}
或
var patterns = new[] { "Type1", "Type2", "Type3" };
var match = patterns
.Select(p => Regex.Match(input, p))
.FirstOrDefault(m => m.Success);
// In your original example, match will be the last match if all are
// unsuccessful. I expect this is an accident, but if you want this
// behavior, you can do this instead:
var match = patterns
.Select(p => Regex.Match(input, p))
.FirstOrDefault(m => m.Success)
?? Regex.Match(input, patterns[patterns.Length - 1]);
因为LINQ to Objects使用延迟执行,所以只有在找到匹配项之前才会调用Regex.Match
,所以您不必担心这种方法过于急切。
是的,我会这样写,以避免多次执行Regex匹配:
match = Regex.Match(input, @"Type1|Type2|Type3");
if (match.Success)
{
// loop, in case you are matching to multiple occurrences within the input.
// However, Regex.Match(string, string) will only match to the first occurrence.
foreach (Capture capture in match.Captures)
{
// if you care to determine which one (Type1, Type2, or Type3) each capture is
switch (capture.Value)
{
case "Type1":
// ...
break;
case "Type2":
// ...
break;
case "Type3":
// ...
break;
}
}
}
或者,如果你有一个想要检查的模式的任意列表:
// assumption is that patterns contains a list of valid Regex expressions
match = Regex.Match(input, string.Join("|", patterns));
if (match.Success)
{
// obviously, only one of these return statements is needed
// return the first occurrence
return match.Captures[0].Value;
// return an IEnumerable<string> of the matched patterns
return match.Captures.OfType<Capture>().Select(capture => capture.Value);
}
这里是另一种方法,它使用命名的捕获组来索引每个模式。当找到匹配时,我们尝试确定哪个捕获组匹配。
我非常不喜欢这个代码,因为"模式"和索引重复不必要的串联,但我不知道如何做到这一点:
编辑:我已经用字典清理了一些代码
// assumption is that patterns contains a list of valid Regex expressions
int i = 0;
var mapOfGroupNameToPattern = patterns.ToDictionary(pattern => "Pattern" + (i++));
match = Regex.Match(input, string.Join("|", mapOfGroupNameToPattern.Select(x => "(?<" + x.Key + ">" + x.Value + ")")));
if (match.Success)
{
foreach (var pattern in mapOfGroupNameToPattern)
{
if (match.Groups[pattern.Key].Captures.Count > 0)
{
// this is the pattern that was matched
return pattern.Value;
}
}
}
另一种方法。它遍历所有列表,但您可以查找要匹配的变量数或字符串,而无需编写x个if语句。
string input = "Type1";
List<string> stringsToTest = new List<string>() { @"Type1", @"Type2", @"Type3" };
var q = from string t in stringsToTest
where Regex.IsMatch(input, t)
select t;
//This way you can get how many strings on the list matched the input
foreach(string s in q)
{
Console.WriteLine(s);
}