繁体   English   中英

使用Match和Regex

[英]Working With Match and Regex

我正在研究一个解析传入文本文件的项目。 我正在学习C#。 我当前用于挑选所需信息的方法如下:

string MyMatchString = @"a pattern to match";
Match MyMatch = Regex.Match(somestringinput, MyMatchString);
if (MyMatch.Succes)
{
   DoSomething(MyMatch.Value);
}

我正在做很多事情。 我希望能够将比赛和测试成功结合在一起。 浏览类列表,Regex有一个IsMatch()方法,但是看来我不能访问匹配的值(假设它成功了)。 我想我需要一个Match实例。 我试过了

if ((Match MyMatch = Regex.Match(somestringinput, MyMatchString).Success)

但是当然有一个编译错误。

我在考虑采用匹配模式然后输入然后返回布尔值的静态方法。 然后,我可以测试是否成功,如果可以,则获取匹配的值。

您可以使用foreach

string MyMatchString = @"a pattern to match";
foreach (Match match in Regex.Matches(somestringinput, MyMatchString))
{
    DoSomething(match.Value);
}

如果您只想要一个匹配项,则可以选择添加break (或使用.Take(1)

好吧,您可以为Regex编写扩展方法,这将为您提供一些功能。 诀窍在于无需两次运行正则表达式匹配就可以做到这一点,这可能会影响您的性能(请注意:这尚未经过测试,与您的想法不同,它需要一个现成的Regex对象才能工作)。

public static class RegexExtensions {
    public static bool GetMatch(this Regex regex, string input, out string matched) {
        Match match = regex.Match(input);
        if (match.Success) {
            matched = match.Value;
            return true;
        }
        matched = null;
        return false;
    }
}

所以你会做类似的事情

string matched;
Regex regex = new Regex(pattern);
if (regex.GetMatch(inputstring, matched))
{ /* do something with 'matched' */ }
else
{ /* no match, 'matched' is null */ }

您可能更愿意在失败的情况下只返回null,否则返回字符串,而不必使用boolean和output参数。

您可以实现TryParseTryGetValue使用的“ Try”约定。

public static bool TryMatch(string input, string pattern, out Match match)
{
    var m = Regex.Match(input, pattern);
    if(m.Success)
    {
        match = m;
    }
    return m.Success;
}

// usage
string myMatchString = @"a pattern to match"; 
Match result = null;
if(TryMatch(somestringinput, myMatchString, out result))
{
    DoSomething(result.Value);
}

或者,您可以创建接受ActionFunc委托的高阶函数。

public void ActionOnMatch(string input, string pattern, Action<string> action)
{
    var m = Regex.Match(input, pattern);
    if(m.Success)
    {
        action(m.Value);
    }
}

public TResult FuncOnMatch<TResult>(string input, string pattern, 
    Func<string, TResult> func)
{
    var m = Regex.Match(input, pattern);
    if(m.Success)
    {
        return func(m.Value);
    }
    else
    {
        return default(TResult);
    }
}

/// usage
string pattern = @"a pattern to match"; 
ActionOnMatch(input, pattern, DoSomething);
var result = FuncOnMatch<string>(input, pattern, (val) => val);

如果您只想将答案作为布尔值而不希望存储它,则不要使用变量匹配来存储它。 您可以只使用Regex.Match来获取所需的布尔值,如下所示:

if (Regex.Match("a", MyMatchString).Success) { };

根据设计,创建比赛,测试成功和使用结果是单独的步骤。 可能有一些解决方法,但是您可能会与框架发生冲突,并可能使代码对其他开发人员的可读性降低

如果要解析文件,则可以考虑使用Linq的另一种方法。 根据DoSomething确切含义,这至少可以使代码少一点乏味。

Regex re = new Regex(@"(?<prop1>pattern part 1)(?<prop2>pattern part 2)");

var goodLines = 
    from line in File.ReadAllLines(inputFile)
    let m = re.Match(line)
    where m.Success
    select new {
        Prop1 = m.Groups["prop1"].ToString(),
        Prop2 = m.Groups["prop2"].ToString()
    }

foreach (var goodLine in goodLines) {
    DoSomething(goodLine);
}

在这里,我们在正则表达式中定义命名捕获组,并使用这些命名捕获来填充匿名类型。 然后,我们遍历Linq表达式返回的那些匿名对象的集合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM