comment valider les caractères ET les mots dans regex?
Le contexte
J'ai besoin d'un peu de code qui prend une chaîne mathématique très simple et exécute la eval()
fonction PHP . Par exemple ...
$math = '25 * (233 - 1.5)';
echo eval("return $math;"); // returns 5787.5
Cependant, eval()
c'est assez dangereux entre de mauvaises mains, donc la variable doit être nettoyée. Pour ce qui précède, par exemple, un simple preg_replace serait ...
$math = '25 * (233 - 1.5)';
$replace = '/[^0-9\(\)\.\,\+\-\*\/\s]/';
$math = preg_replace($replace, '', $math);
echo eval("return $math;"); // returns 5787.5
... qui garantit $math
ne contient que des caractères valides ... .,+-*/
, des espaces et des chiffres, et aucun code malveillant.
La question
Je veux laisser quelques mots très spécifiques (fonctions mathématiques PHP), tels que pow
, pi
, min
, max
, etc.
Quelle est la manière la plus propre de valider les caractères et les mots dans les regex?
Donc, si on lui donne cette chaîne ...
pow(25,2) / pi(); hack the pentagon;
... comment supprimer tout ce qui n'était pas dans l' $replace
expression régulière, mais conserver les mots pow
et pi
?
En utilisant php, vous pouvez faire correspondre les mots que vous ne souhaitez pas supprimer et utiliser une approche (* SKIP) (* FAIL) .
Vous pouvez également raccourcir la classe de caractères en supprimant les barres obliques inverses, et si vous utilisez un délimiteur différent de celui /
de php, vous n'avez pas non plus à échapper le/
Lorsque vous remplacez les caractères correspondants dans la classe de caractères par une chaîne vide, vous pouvez utiliser un quantificateur +
pour faire correspondre une ou plusieurs correspondances consécutives et effectuer un seul remplacement.
\b(?:p(?:i|ow)|m(?:in|ax))\b(*SKIP)(*FAIL)|[^0-9().,+*/\s-]+
Le motif correspond
\b(?:p(?:i|ow)|m(?:in|ax))\b
Match soitpi
pow
min
oumax
(*SKIP)(*FAIL)|
Les correspondances jusqu'à présent ne doivent pas faire partie du résultat[^0-9().,+*/\s-]+
Correspond à 1+ fois n'importe quel caractère sauf les caractères listés dans la classe de caractères annulée
Si vous ne voulez pas les espaces au début et à la fin, vous pouvez envisager de couper $math
$math = 'pow(25,2) / pi(); hack the pentagon;';
$replace = '~\b(?:p(?:i|ow)|m(?:in|ax))\b(*SKIP)(*FAIL)|[^0-9().,+*/\s-]+~';
$math = preg_replace($replace, '', $math);
echo eval("return $math;"); // returns 198.94367886487