2012-03-17 27 views
5

Estoy luchando por encontrar la mejor manera de hacerlo. Básicamente, me proporcionan cadenas que son así con la tarea de imprimir la cadena con las matemáticas analizadas.PHP - Analizar ecuaciones matemáticas dentro de las cadenas

Jack tiene un [0.8 * 100]% de posibilidades de pasar la prueba. Katie tiene un [(0.25 + 0.1) * 100]% de posibilidades.

Las ecuaciones matemáticas siempre están encapsuladas entre corchetes. ¡Por qué estoy lidiando con este tipo de cadenas es una larga historia, pero realmente agradecería la ayuda!

+0

preg_match_all + eval + str_replace (o con preg_replace_callback) ... en ese orden. pero ten cuidado, la evaluación puede ser peligrosa, no coincida con [] o alguien podría agregar código en []. – Rufinus

+0

Puede 'eval()' las declaraciones, eso es un riesgo de seguridad. – Robus

Respuesta

2
preg_match_all('/\[(.*?)\]/', $string, $out); 
foreach ($out[1] as $k => $v) 
{ 
    eval("\$result = $v;"); 
    $string = str_replace($out[0][$k], $result, $string); 
} 

Este código es altamente peligroso si las cadenas son las entradas del usuario, ya que permite cualquier código arbitrario ejecutado

+0

No hay entrada de usuario por lo que funcionó maravillosamente. ¡Gracias hombre! – user949738

-2

Sonidos, como su tarea ... pero lo que sea.

Tienes que usar la manipulación de cadenas php tiene muchas funciones incorporadas para que tengas suerte. Compruebe la función de explosión() para seguro y str_split().

Aquí está una lista completa de las funciones relacionadas específicamente con cadenas: http://www.w3schools.com/php/php_ref_string.asp

buena suerte.

+0

No es tarea ... tal vez tienes esa impresión de mi ejemplo ficticio? explotar() es una idea bastante incompleta. – user949738

3

Hay un montón de bibliotecas de evaluación de matemáticas para PHP. Una búsqueda rápida en la web aparece this one.


Escribir su propio programa de análisis es también una opción, y si es sólo aritmética básica no debería ser demasiado difícil. Con los recursos que hay, me mantendría alejado de esto.


Puede tener un enfoque más simple y usar eval. Tenga cuidado de desinfectar su entrada primero. En el eval docs's page, hay comentarios con código para hacer eso. Aquí hay un ejemplo:

Descargo de responsabilidad: Sé que eval es solo una falta de ortografía del mal, y es algo horrible y horrible, y todo eso. Si se usa correctamente, tiene usos, sin embargo.

<?php 

$test = '2+3*pi'; 

// Remove whitespaces 
$test = preg_replace('/\s+/', '', $test); 

$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number 
$functions = '(?:sinh?|cosh?|tanh?|abs|acosh?|asinh?|atanh?|exp|log10|deg2rad|rad2deg|sqrt|ceil|floor|round)'; // Allowed PHP functions 
$operators = '[+\/*\^%-]'; // Allowed math operators 
$regexp = '/^(('.$number.'|'.$functions.'\s*\((?1)+\)|\((?1)+\))(?:'.$operators.'(?2))?)+$/'; // Final regexp, heavily using recursive patterns 

if (preg_match($regexp, $q)) 
{ 
    $test = preg_replace('!pi|π!', 'pi()', $test); // Replace pi with pi function 
    eval('$result = '.$test.';'); 
} 
else 
{ 
    $result = false; 
} 

?> 
+0

Acepto, excepto por la muestra del código de evaluación (no funciona para mí). – davidmars

0

El enfoque eval actualizada de ejemplos PHP doc.

<?php 
function calc($equation) 
{ 
    // Remove whitespaces 
    $equation = preg_replace('/\s+/', '', $equation); 
    echo "$equation\n"; 

    $number = '((?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?|pi|π)'; // What is a number 

    $functions = '(?:sinh?|cosh?|tanh?|acosh?|asinh?|atanh?|exp|log(10)?|deg2rad|rad2deg|sqrt|pow|abs|intval|ceil|floor|round|(mt_)?rand|gmp_fact)'; // Allowed PHP functions 
    $operators = '[\/*\^\+-,]'; // Allowed math operators 
    $regexp = '/^([+-]?('.$number.'|'.$functions.'\s*\((?1)+\)|\((?1)+\))(?:'.$operators.'(?1))?)+$/'; // Final regexp, heavily using recursive patterns 

    if (preg_match($regexp, $equation)) 
    { 
     $equation = preg_replace('!pi|π!', 'pi()', $equation); // Replace pi with pi function 
     echo "$equation\n"; 
     eval('$result = '.$equation.';'); 
    } 
    else 
    { 
     $result = false; 
    } 
    return $result; 
} 
?> 
Cuestiones relacionadas