Проверить, является ли строка регулярным выражением
Есть ли хороший способ тестирования, если строка является регулярным выражением или обычной строкой в PHP?
В идеале я хочу написать функцию для запуска строки через, которая возвращает true или false.
Я посмотрел preg_last_error()
:
<?php
preg_match('/[a-z]/', 'test');
var_dump(preg_last_error());
preg_match('invalid regex', 'test');
var_dump(preg_last_error());
?>
Где, очевидно, первая ошибка не является, а вторая. Но preg_last_error()
возвращает int 0
оба раза.
Любые идеи?
Ответы
Ответ 1
Единственный простой способ проверить правильность регулярного выражения в PHP - использовать его и проверить, не выдается ли предупреждение.
ini_set('track_errors', 'on');
$php_errormsg = '';
@preg_match('/[blah/', '');
if($php_errormsg) echo 'regex is invalid';
Однако использование произвольного пользовательского ввода в качестве регулярного выражения является плохой идеей. В процессоре PCRE раньше были дыры безопасности (переполнение буфера = > удаленное выполнение кода), и возможно было бы создать специально созданные длинные регулярные выражения, для которых требуется много компиляции/памяти для компиляции/выполнения.
Ответ 2
Самый простой способ проверить, является ли строка регулярным выражением:
if( preg_match("/^\/.+\/[a-z]*$/i",$regex))
Это скажет вам, есть ли у строки хорошая вероятность быть в качестве регулярного выражения. Однако существует много строк, которые передают эту проверку, но не могут быть регулярным выражением. Невыбежденные косые черты в середине, неизвестные модификаторы в конце, несогласованные круглые скобки и т.д. Могут вызвать проблемы.
Причина preg_last_error
возвращает 0, потому что "недопустимое регулярное выражение" не является:
- PREG_INTERNAL_ERROR (внутренняя ошибка)
- PREG_BACKTRACK_LIMIT_ERROR (чрезмерное принудительное обратное отслеживание)
- PREG_RECURSION_LIMIT_ERROR (чрезмерно рекурсивно)
- PREG_BAD_UTF8_ERROR (плохо форматированный UTF-8)
- PREG_BAD_UTF8_OFFSET_ERROR (смещение до середины символа UTF-8)
Ответ 3
Почему бы просто не использовать... другое регулярное выражение? Три линии, no @
kludges или что-то еще:
// Test this string
$str = "/^[A-Za-z ]+$/";
// Compare it to a regex pattern that simulates any regex
$regex = "/^\/[\s\S]+\/$/";
// Will it blend?
echo (preg_match($regex, $str) ? "TRUE" : "FALSE");
Или, в форме функции, еще более симпатично:
public static function isRegex($str0) {
$regex = "/^\/[\s\S]+\/$/";
return preg_match($regex, $str0);
}
Это не проверяет достоверность; но похоже, что вопрос Is there a good way of test if a string is a regex or normal string in PHP?
, и он делает это.
Ответ 4
Вот хороший ответ:
fooobar.com/info/93863/...
if(@preg_match($yourPattern, null) === false){
//pattern is broken
}else{
//pattern is real
}