2012-01-11 24 views
10

Estoy escribiendo una clase de validación de formulario y deseo incluir expresiones regulares en la validación. Por lo tanto, no se garantiza que la expresión regular proporcionada sea válida.Pruebe si una expresión regular es válida en PHP

¿Cómo puedo (de manera eficiente) verificar que la expresión regular sea válida?

Respuesta

15

Use el patrón en sus llamadas preg_*. Si la función devuelve false, es probable que haya un problema con su patrón. Hasta donde yo sé, esta es la forma más fácil de verificar si un patrón de expresiones regulares es válido en PHP.


He aquí un ejemplo que especifica el tipo de cheque booleano:

$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 
} 
+2

Solo para enfatizar, eso es estrictamente ('===') Booleano 'falso', no un valor de falsy (' == ') como' 0'. – Wiseguy

+0

Eso parece funcionar. Pensé que el preg_ * devolvería falso si no coincidía con la expresión, dando falsos positivos. – CrazeD

+2

@CrazeD Dependiendo de la función llamada y de la opción aprobada, podría tratarse de una variedad de valores. Para lo anterior, si '$ subject' no coincide con' $ pattern', y fue válido, devolverá '0'. Sin embargo, 'preg_replace' devolverá' NULL' en caso de falla en lugar de falsa. Simplemente tendrá que mirar los documentos para la función particular que está utilizando. – cspray

-7

Ésta es mi solución usando la próxima advertencia si algo está mal con la expresión:

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; 
} 
+4

-1 para código poco claro, 'rand()', 'eval()' y '+ 0'. – Dan

+0

En serio, he logrado encontrar el camino de regreso y todavía no tengo absolutamente ninguna idea sobre este fragmento; ¿Qué demonios está haciendo? – Dan

+0

Este es un try-catch personalizado. Es muy horrible de leer, pero probablemente funcione. Simplemente usaría try-catch. – twicejr

1

Cuando tiene informes de errores, no puede salirse con la suya simplemente probando el resultado booleano. Si la expresión regular falla, se emiten advertencias (es decir, 'Advertencia: no se ha encontrado el delimitador final xxx'.)

Lo que me parece extraño, es que la documentación de PHP no dice nada acerca de estas advertencias arrojadas.

Debajo está mi solución para este problema, usando 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; 
    } 
} 
2

No debe estar utilizando @ para silenciar todos los errores porque también silencia los errores fatales.

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

Esto solo silencia las advertencias para la llamada a preg_match.

Cuestiones relacionadas