Can delimiter errors be missing in preg / PHP regexp programmatically?

I need to determine if a regex is valid so that invalid ones can gracefully be rejected in the UI. Stack overflow is a clever abomination to do this with another regex that I plan to strenuously avoid.

There is a much simpler approach of doing match and error checking that returns the correct boolean result, but it would be interesting to get the reason for the failure / message as well:

// The error is that preg delimiters are missing
$testRegex = 'Location: (.+)';

// This bit is fine
$result = preg_match($testRegex, ''); // returns false i.e. failure
$valid = is_int($result); // false, i.e. the regex is invalid

// Returns PREG_NO_ERROR, which means no error occured
echo preg_last_error() . "\n";

      

If I run this I get it right:

PHP Warning: preg_match (): delimiter must not be alphanumeric or backslash in ... on line ...

However, the output of the error function 0

, which is PREG_NO_ERROR

. I would think this would return a non-zero error code - and it would be even better if I could get a clean version of the warning message.

It is of course possible that this is not available at all (i.e. only available for PHP's engine to print a warning). I am running 5.5.3-1ubuntu2.6 (cli)

.

+3


source to share


2 answers


This should work for you:

Here I am just enabling output buffering with ob_start()

. Then I commit the last error with error_get_last()

. Then I finish buffering the output ob_end_clean()

. After that you can check if the array is empty and if no error occurred.

ob_start();
$result = preg_match(".*", "Location: xy");
$error = error_get_last();
ob_end_clean();

if(!empty($error))
    echo "<b>Error:</b> " . $error["message"];
else
    echo "no error found!";

      

output:

Error: preg_match (): No ending delimiter '.' found


EDIT:

If you want, you can create your own error handler which basically just throws an exception for every error you usually get.

Then you can put your code in a block try - catch

and catch the exception.

set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
    // error was suppressed with the @-operator
    if (0 === error_reporting()) {
        return false;
    }
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try {
    $result = preg_match(".*", "Location: xy");
} catch(Exception $e) {
    echo "<b>Error:</b> " . $e->getMessage();
}

      

Code for an error handler from Philip Gerber in this answer

+2


source


Perhaps you could use error_get_last()

to get a little more information.

Array
(
    [type] => 2
    [message] => preg_match(): Delimiter must not be alphanumeric or backslash
    [file] => /Users/ivan/Desktop/test.php
    [line] => 6
)

      

type

- E_WARNING

and you can safely guess the function name string from the part message

, as it will always be in the same format.

Then you can do

$lastError = error_get_last()['message']; // php 5.5 expression
if(strpos($lastError, 'preg_match(): ') === 0){
    $error = substr($lastError, 14);
}

      



And $error

will be var_dump

'ed up

string(47) "Delimiter must not be alphanumeric or backslash"

      

Or a null

Also, in response to another answer, you can turn off warnings using @preg_match(...)

so that you don't have to handle the output buffers yourself. error_get_last()

will catch the error anyway.

+1


source







All Articles