Test if a regular expression is a valid one in PHP

前端 未结 6 1920
太阳男子
太阳男子 2020-12-16 14:24

I am writing a form validation class and wish to include regular expressions in the validation. Therefore, the regex provided isn\'t guaranteed to be valid.

How can

相关标签:
6条回答
  • 2020-12-16 14:57

    This is my solution using the upcoming warning if something is wrong with the expression:

    function isRegEx($test)
    {
        $notThisLine = error_get_last();
        $notThisLine = isset($notThisLine['line']) ? $notThisLine['line'] + 0 : 0;
        while (($lines = rand(1, 100)) == $notThisLine);
        eval(
            str_repeat("\n", $lines) . 
            '@preg_match(\'' . addslashes($test) . '\', \'\');'
        );
        $check = error_get_last();
        $check = isset($check['line']) ? $check['line'] + 0 : 0;
        return $check == $notThisLine;
    }
    
    0 讨论(0)
  • 2020-12-16 15:05

    When you have error reporting on, you can't get away with simply testing the boolean result. If the regex fails warnings are thrown (i.e. 'Warning: No ending delimiter xxx found'.)

    What I find odd, is that the PHP documentation tells nothing about these thrown warnings.

    Below is my solution for this problem, using try, catch.

    //Enable all errors to be reported. E_WARNING is what we must catch, but I like to have all errors reported, always.
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    
    //My error handler for handling exceptions.
    set_error_handler(function($severity, $message, $file, $line)
    {
        if(!(error_reporting() & $severity))
        {
            return;
        }
        throw new ErrorException($message, $severity, $severity, $file, $line);
    });
    
    //Very long function name for example purpose.
    function checkRegexOkWithoutNoticesOrExceptions($test)
    {
        try
        {
            preg_match($test, '');
            return true;
        }
        catch(Exception $e)
        {
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-12-16 15:14

    Use the pattern in your preg_* calls. If the function returns false there is likely a problem with your pattern. As far as I know this is the easiest way to check if a regex pattern is valid in PHP.


    Here's an example specifying the right kind of boolean check:

    $invalidPattern = 'i am not valid regex';
    $subject = 'This is some text I am searching in';
    if (@preg_match($invalidPattern, $subject) === false) {
        // the regex failed and is likely invalid
    }
    
    0 讨论(0)
  • 2020-12-16 15:15

    Anyone still looking at this question anno 2018, and is using php 7, should be using try/catch.

    try { 
        preg_match($mypattern, '');
    } catch (\Throwable $exception) {
        // regex was invalid and more info is in $exception->getMessage()
    }
    
    0 讨论(0)
  • 2020-12-16 15:16

    You shouldn't be using @ to silence all errors because it also silences fatal errors.

    function isRegularExpression($string) {
      set_error_handler(function() {}, E_WARNING);
      $isRegularExpression = preg_match($string, "") !== FALSE;
      restore_error_handler();
      return isRegularExpression;
    }
    

    This only silences warnings for the preg_match call.

    0 讨论(0)
  • 2020-12-16 15:20

    PHP has progressed quite a bit since this question was first asked (and answered). You can now (PHP 5.2+) simply write the following to, not only test if the regular expression is valid, but to get the detailed error message if it's not:

    if(@preg_match($pattern, '') === false){
       echo error_get_last()["message"];
    }
    

    Placed in a function

    /**
     * Return an error message if the given pattern argument or its underlying regular expression
     * are not syntactically valid. Otherwise (if they are valid), NULL is returned.
     *
     * @param $pattern
     *
     * @return string|null
     */
    function regexHasErrors($pattern): ?string
    {
        if(@preg_match($pattern, '') === false){
            //Silence the error by using a @
    
            return str_replace("preg_match(): ", "", error_get_last()["message"]);
            //Make it prettier by removing the function name prefix
        }
        return NULL;
    }
    

    Demo

    0 讨论(0)
提交回复
热议问题