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
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;
}
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;
}
}
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
}
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()
}
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.
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