php - vacio - expresiones regulares espacio en blanco
¿Cómo puedo validar regex? (10)
Me gustaría probar la validez de una expresión regular en PHP, preferiblemente antes de que se use. ¿Es la única manera de hacer esto probar un preg_match()
y ver si devuelve FALSE
?
¿Hay una forma más simple / adecuada de probar una expresión regular válida?
Creé una función simple que se puede llamar para verificar preg
function is_preg_error()
{
$errors = array(
PREG_NO_ERROR => ''Code 0 : No errors'',
PREG_INTERNAL_ERROR => ''Code 1 : There was an internal PCRE error'',
PREG_BACKTRACK_LIMIT_ERROR => ''Code 2 : Backtrack limit was exhausted'',
PREG_RECURSION_LIMIT_ERROR => ''Code 3 : Recursion limit was exhausted'',
PREG_BAD_UTF8_ERROR => ''Code 4 : The offset didn/'t correspond to the begin of a valid UTF-8 code point'',
PREG_BAD_UTF8_OFFSET_ERROR => ''Code 5 : Malformed UTF-8 data'',
);
return $errors[preg_last_error()];
}
Puede llamar a esta función usando el siguiente código:
preg_match(''/(?:/D+|</d+>)*[!?]/'', ''foobar foobar foobar'');
echo is_preg_error();
Alternativa - Probador en línea de expresión regular
De acuerdo con la referencia PCRE , no existe una forma de probar la validez de una expresión, antes de ser utilizada. Pero creo que si alguien usa una expresión no válida, es un error de diseño en esa aplicación, no en tiempo de ejecución, por lo que debería estar bien.
Entonces, en resumen, para todos los que llegan a esta pregunta, puede validar expresiones regulares en PHP con una función como esta.
preg_match () devuelve 1 si el patrón coincide con el sujeto dado, 0 si no es así o FALSO si ocurre un error. - Manual de PHP
/**
* Return an error message if the regular expression is invalid
*
* @param string $regex string to validate
* @return string
*/
function invalidRegex($regex)
{
if(preg_match($regex, null) !== false)
{
return '''';
}
$errors = array(
PREG_NO_ERROR => ''Code 0 : No errors'',
PREG_INTERNAL_ERROR => ''Code 1 : There was an internal PCRE error'',
PREG_BACKTRACK_LIMIT_ERROR => ''Code 2 : Backtrack limit was exhausted'',
PREG_RECURSION_LIMIT_ERROR => ''Code 3 : Recursion limit was exhausted'',
PREG_BAD_UTF8_ERROR => ''Code 4 : The offset didn/'t correspond to the begin of a valid UTF-8 code point'',
PREG_BAD_UTF8_OFFSET_ERROR => ''Code 5 : Malformed UTF-8 data'',
);
return $errors[preg_last_error()];
}
Que se puede usar así
if($error = invalidRegex(''/foo//''))
{
die($error);
}
Me inclinaría a configurar una serie de pruebas unitarias para tu expresión regular. De esta manera, no solo podrá asegurarse de que la expresión regular sea válida, sino que también sea efectiva para la coincidencia.
Creo que usar TDD es una forma efectiva de desarrollar expresiones regex y significa que ampliarlo en el futuro se simplifica ya que ya tienes todos tus casos de prueba disponibles.
La respuesta a esta pregunta tiene una gran respuesta para configurar tus pruebas unitarias.
No estoy seguro si es compatible con PCRE, pero hay una extensión de Chrome en https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib llamado https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib . Todavía no lo he usado, así que no puedo responderlo, pero ¿podría ser útil?
Puede validar su expresión regular con una expresión regular y hasta un cierto límite . Consulte esta respuesta de desbordamiento de pila para obtener más información.
Nota: una "expresión regular recursiva" no es una expresión regular, y esta versión extendida de regex no coincide con las expresiones regulares extendidas.
Una mejor opción es usar preg_match
y hacer coincidir contra NULL como said @Claudrian
Puede verificar si es una expresión regular sintácticamente correcta con esta pesadilla de una expresión regular, si su motor admite la recursión (debería hacerlo PHP).
No puede, sin embargo, decir algorítmicamente si dará los resultados que desea sin ejecutarlo.
De: ¿Hay una expresión regular para detectar una expresión regular válida?
/^((?:(?:[^?+*{}()[/]//|]+|//.|/[(?:/^?//.|/^[^//]|[^//^])(?:[^/]//]+|//.)*/]|/((?:/?[:=!]|/?<[=!]|/?>)?(?1)??/)|/(/?(?:R|[+-]?/d+)/))(?:(?:[?+*]|/{/d+(?:,/d*)?/})[?+]?)?|/|)*)$/
Si quieres probar dinámicamente una expresión regular preg_match(...) === false
parece ser tu única opción. PHP no tiene un mecanismo para compilar expresiones regulares antes de ser usadas.
Además, es posible que preg_last_error una función útil.
Por otro lado, si tienes una expresión regular y solo quieres saber si es válida antes de usarla, hay muchas herramientas disponibles. Encontré rubular.com para ser agradable de usar.
Sin ejecutar realmente la expresión regular, no hay forma de estar seguro de si es válida. Recientemente implementé un RegexValidator similar para Zend Framework. Funciona bien
<?php
class Nuke_Validate_RegEx extends Zend_Validate_Abstract
{
/**
* Error constant
*/
const ERROR_INVALID_REGEX = ''invalidRegex'';
/**
* Error messages
* @var array
*/
protected $_messageTemplates = array(
self::ERROR_INVALID_REGEX => "This is a regular expression PHP cannot parse.");
/**
* Runs the actual validation
* @param string $pattern The regular expression we are testing
* @return bool
*/
public function isValid($pattern)
{
if (@preg_match($pattern, "Lorem ipsum") === false) {
$this->_error(self::ERROR_INVALID_REGEX);
return false;
}
return true;
}
}
// This is valid, both opening ( and closing )
var_dump(preg_match(''~Valid(Regular)Expression~'', null) === false);
// This is invalid, no opening ( for the closing )
var_dump(preg_match(''~InvalidRegular)Expression~'', null) === false);
Como dijo el usuario pozs , también considere poner @
en frente de preg_match () ( @preg_match()
) en un entorno de prueba para evitar advertencias o avisos.
Para validar un RegExp solo ejecútelo contra null
(no es necesario conocer los datos que desea probar por adelantado) . Si devuelve falso explícito ( === false
), está roto. De lo contrario, es válido, aunque no debe coincidir con nada.
Por lo tanto, no es necesario que escriba su propio validador RegExp. Es tiempo perdido ...