2012-01-11 10 views
10

Sto scrivendo una classe di convalida del modulo e desidero includere espressioni regolari nella convalida. Pertanto, la regex fornita non è garantita per essere valida.Verificare se un'espressione regolare è valida in PHP

Come è possibile (in modo efficiente) verificare che la regex sia valida?

risposta

15

Utilizzare lo schema nelle chiamate preg_*. Se la funzione restituisce false probabilmente c'è un problema con il tuo pattern. Per quanto ne so questo è il modo più semplice per verificare se un pattern regex è valido in PHP.


Ecco un esempio specificando il giusto tipo di controllo booleana:

$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

Giusto per sottolineare, questo è rigorosamente ('===') Booleano 'falso', non un valore falsy (' == ') come' 0'. – Wiseguy

+0

Sembra funzionare. Ho pensato che preg_ * avrebbe restituito false se non corrispondesse all'espressione, dando quindi falsi positivi. – CrazeD

+2

@CrazeD A seconda della funzione chiamata e dell'opzione passata potrebbe essere una varietà di valori. Per quanto sopra se '$ subject' non corrisponde a' $ pattern', ed era valido, restituirà '0'. Tuttavia, 'preg_replace' restituirà' NULL' in caso di errore invece che falso. Dovrai solo guardare i documenti per la particolare funzione che stai usando. – cspray

-7

Questa è la mia soluzione che utilizza l'avvertimento imminente se qualcosa non va con l'espressione:

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 per codice non chiaro, 'rand()', 'eval()' e '+ 0'. – Dan

+0

Seriamente, sono riuscito a trovare la strada per tornare qui e non ho ancora assolutamente idea di questo frammento; cosa diavolo sta facendo? – Dan

+0

Questo è un try-catch con codice personalizzato. Molto orribile da leggere ma probabilmente funziona. Vorrei semplicemente usare try-catch. – twicejr

1

Quando si avere segnalazioni di errori su, non si può farla franca semplicemente testando il risultato booleano. Se la regex fallisce vengono lanciati degli avvisi (ad esempio: "Nessun delimitatore finale trovato xxx")

Ciò che trovo strano è che la documentazione di PHP non dice nulla di questi avvisi lanciati.

Di seguito è la mia soluzione per questo problema, utilizzando 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

Non si dovrebbe utilizzare @ per disattivare tutti gli errori perché silenzia anche gli errori irreversibili.

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

Questo solo silenzi avvertenze per la chiamata preg_match.

Problemi correlati