2012-03-17 12 views
5

Staram się znaleźć najlepszy sposób na zrobienie tego. Zasadniczo dostaję ciągi, które są podobne do tego z zadaniem drukowania ciągów z analizowaną matematyką.PHP - Parse równań matematycznych wewnątrz ciągów znaków

Jack ma [0,8 * 100]% szans na zaliczenie testu. Katie ma szansę [(0,25 + 0,1) * 100]%.

Równania matematyczne są zawsze hermetyzowane za pomocą nawiasów kwadratowych. Dlaczego mam do czynienia z takimi ciągami, to długa historia, ale naprawdę doceniam pomoc!

+0

preg_match_all + eval + str_replace (lub z preg_replace_callback) ... w tej kolejności. ale bądź ostrzeżony, eval może być niebezpieczny, nie pasuje tylko na [] lub ktoś może dodać kod w []. – Rufinus

+0

Możesz "eval()" instrukcji, to jednak ryzyko bezpieczeństwa. – Robus

Odpowiedz

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

Ten kod jest wysoce niebezpieczne, jeśli struny są dane wprowadzane przez użytkownika, ponieważ pozwala dowolny arbitralny kod wykonywany

+0

Brak danych wprowadzanych przez użytkownika, aby działało pięknie. Dzięki! – user949738

-2

Brzmi jak twoja praca domowa ... ale cokolwiek.

Musisz użyć manipulacji ciągiem php ma wiele wbudowanych funkcji, więc masz szczęście. Sprawdź na pewno funkcję explode() i str_split().

Oto pełna lista funkcji specyficznie związanych z ciągów: http://www.w3schools.com/php/php_ref_string.asp

powodzenia.

+0

Nie zadanie domowe ... może masz takie wrażenie z mojego fikcyjnego przykładu? explode() to dość szkicowy pomysł. – user949738

3

Istnieje wiele bibliotek oceny matematyki dla PHP. Szybkie wyszukiwanie w Internecie pojawia się this one.


pisanie własnego parsera jest również opcja, a jeśli to tylko podstawowa arytmetyka nie powinno być zbyt trudne. Dzięki tym zasobom trzymałbym się z dala od tego.


Można przyjąć prostsze podejście i użyć eval. Bądź ostrożny, aby najpierw odfiltrować dane wejściowe. Na eval docs's page znajdują się komentarze z kodem do tego. Oto jeden przykład:

Nota prawna: Wiem, że eval to po prostu błędna pisownia zła, a to straszna rzecz, i to wszystko. Jeśli jest używany, ma swoje zastosowania.

<?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

Zgadzam się, z wyjątkiem próbki kodu eval (nie działa dla mnie). – davidmars

0

Podejście eval zaktualizowane z przykładów doc do PHP.

<?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; 
} 
?> 
Powiązane problemy