我可以在不抛出异常的情况下测试正则表达式在 C# 中是否有效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/218680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:36:53  来源:igfitidea点击:

Can I test if a regex is valid in C# without throwing exception

c#regex

提问by Mark S. Rasmussen

I allow users to enter a regular expression to match IP addresses, for doing an IP filtration in a related system. I would like to validate if the entered regular expressions are valid as a lot of userse will mess op, with good intentions though.

我允许用户输入正则表达式来匹配 IP 地址,以便在相关系统中进行 IP 过滤。我想验证输入的正则表达式是否有效,因为很多用户都会把操作弄得一团糟,尽管是出于好意。

I can of course do a Regex.IsMatch() inside a try/catch and see if it blows up that way, but are there any smarter ways of doing it? Speed is not an issue as such, I just prefer to avoid throwing exceptions for no reason.

我当然可以在 try/catch 中执行 Regex.IsMatch() 并查看它是否会以这种方式爆炸,但是有没有更聪明的方法来做到这一点?速度本身不是问题,我只是更喜欢避免无缘无故地抛出异常。

采纳答案by Robert

As long as you catch very specific exceptions, just do the try/catch.

只要您捕获非常具体的异常,只需执行 try/catch。

Exceptions are not evil if used correctly.

如果使用得当,例外并不是邪恶的。

回答by Tomalak

A malformed regex isn't the worst of reasons for an exception.

格式错误的正则表达式并不是导致异常的最糟糕的原因。

Unless you resign to a verylimited subset of regex syntax - and then write a regex (or a parser) for that - I think you have no other way of testing if it is valid but to try to build a state machine from it and make it match something.

除非您接受非常有限的正则表达式语法子集 - 然后为此编写正则表达式(或解析器) - 我认为您没有其他方法可以测试它是否有效,只能尝试从中构建状态机并制作它匹配的东西。

回答by Mark Brackett

Not without a lot of work. Regex parsing can be pretty involved, and there's nothing public in the Framework to validate an expression.

不是没有很多工作。正则表达式解析可能非常复杂,并且框架中没有任何公开内容来验证表达式。

System.Text.RegularExpressions.RegexNode.ScanRegex() looks to be the main function responsible for parsing an expression, but it's internal (and throws exceptions for any invalid syntax anyway). So you'd be required to reimplement the parse functionality - which would undoubtedly fail on edge cases or Framework updates.

System.Text.RegularExpressions.RegexNode.ScanRegex() 看起来是负责解析表达式的主要函数,但它是内部函数(无论如何都会抛出任何无效语法的异常)。因此,您需要重新实现解析功能——这在边缘情况或框架更新时无疑会失败。

I think just catching the ArgumentException is as good an idea as you're likely to have in this situation.

我认为在这种情况下捕获 ArgumentException 是一个好主意。

回答by theraccoonbear

In .NET, unless you write your own regular expression parser (which I would strongly advise against), you're almost certainly going to need to wrap the creation of the new Regex object with a try/catch.

在 .NET 中,除非您编写自己的正则表达式解析器(我强烈建议不要这样做),否则您几乎肯定需要使用 try/catch 来包装新 Regex 对象的创建。

回答by Clinton Pierce

Depending on who the target is for this, I'd be very careful. It's not hard to construct regexes that can backtrack on themselves and eat a lot of CPU and memory -- they can be an effective Denial of Service vector.

取决于目标是谁,我会非常小心。构建可以回溯并占用大量 CPU 和内存的正则表达式并不难——它们可以成为有效的拒绝服务向量。

回答by Jeff Atwood

I think exceptions are OK in this case.

我认为在这种情况下例外是可以的。

Here's what I put together:

这是我整理的:

private static bool IsValidRegex(string pattern)
{
    if (string.IsNullOrEmpty(pattern)) return false;

    try
    {
        Regex.Match("", pattern);
    }
    catch (ArgumentException)
    {
        return false;
    }

    return true;
}

回答by Niharika Singh

By using following method you can check wether your reguler expression is valid or not. here testPattern is the pattern you have to check.

通过使用以下方法,您可以检查您的调节器表达式是否有效。这里 testPattern 是您必须检查的模式。

public static bool VerifyRegEx(string testPattern)
{
    bool isValid = true;
    if ((testPattern != null) && (testPattern.Trim().Length > 0))
    {
        try
        {
            Regex.Match("", testPattern);
        }
        catch (ArgumentException)
        {
            // BAD PATTERN: Syntax error
            isValid = false;
        }
    }
    else
    {
        //BAD PATTERN: Pattern is null or blank
        isValid = false;
    }
    return (isValid);
}

回答by Mohammad Fathi MiMFa

I've ever been use below function and have no problem with that. It uses exception and timeout both, but it's functional. Of course it works on .Net Framework >= 4.5.

我曾经使用过下面的功能并且没有问题。它同时使用异常和超时,但它的功能。当然,它适用于 .Net Framework >= 4.5。

    public static bool IsValidRegexPattern(string pattern, string testText = "", int maxSecondTimeOut = 20)
    {
        if (string.IsNullOrEmpty(pattern)) return false;
        Regex re = new Regex(pattern, RegexOptions.None, new TimeSpan(0, 0, maxSecondTimeOut));
        try { re.IsMatch(testText); }
        catch{ return false; } //ArgumentException or RegexMatchTimeoutException
        return true;
    }