Avatar billede groyk Novice
20. december 2010 - 21:04 Der er 14 kommentarer og
1 løsning

Beregn string UDEN eval

Hej Eksperter

Er der en der har et link eller lign til at kunne beregne en string uden at bruge eval();

et eksempel på den string der skal beregnes

$string = "2/5*100/(7*37)";

Sammen med beregningen skal stringen undersøges om den er VALID.
Avatar billede repox Seniormester
20. december 2010 - 21:08 #1
Du fjerner bare gåseøjnene - voila!
Avatar billede repox Seniormester
20. december 2010 - 21:10 #2
Og hvad er dit kriterie for at kalde en matematisk.beregning for 'valid'?
Avatar billede groyk Novice
20. december 2010 - 21:19 #3
Hej Repox

Fjerner gåseøjene. Ja det er nemt. Har dog svært ved at se hvordan det gøres når stringen bliver genereret ud fra forskellige variabler fra blandt andet mysql.

Den orginale string kan ex. se således ud.

$string = "(cost+100)*1,25";

Dette oversættes så til ex.

$string = "(458+100)*1,25";

Vedr. validitet tænker jeg på om det er et regnestykke. dvs. at såfremt resultatet ikke kan beregnes og blive til decimal er regnestykket IKKE valid.
Avatar billede repox Seniormester
20. december 2010 - 21:38 #4
Du kunne jo have været mere specifik - vi er jo ikke tankelæsere.
Men det kan du ikke uden eval(), hvis den matematiske formel blot er en streng du eksempelvis trækker ud at en database.

Med hensyn til validering, giver din definition meget lidt logisk mening. Hvis dit regnestykke resulterer i 0, er det så ikke validt? Eller er det noget preg_match vi er ude i?
Avatar billede groyk Novice
21. december 2010 - 06:59 #5
Hej repox

Ja jeg kunne have været mere specifik, men når man er i kampens hede tror man jo alle ved hvilket problem man sidder med :-)

Vedr. valideringen tænkte jeg på og stringen overhoved kan beregnes.

ex.

100+10/50*2 - VALID

100+/10/50 - IKKE VALID

100g+50 - IKKE VALID

Såfremt jeg bruger eval, kan jeg så begrænse inputtet til eval således at brugeren ikke kan skrive hvad som helst?

Vil jo kun give lov til udregninger.
Avatar billede repox Seniormester
21. december 2010 - 10:03 #6
Det bliver nogle ret syrede kontroller der skal laves, for at give dig den validering - jeg er slet ikke stærk nok i reg exp til at kunne levere andet end noget der validerer om tegnene er gyldige.

Af ren nysgerrighed, hvad er det så der gør det nødvendigt at gemme beregninger som strenge til senere udregninger?
Avatar billede groyk Novice
21. december 2010 - 12:14 #7
Det er et rabatsystem til vores webportal. Rimeligt kringlet.

Lad os sige vi har en prisgruppe på en vare der hedder detail. Her kan prisen eksempel vis være 100 kr. v. 1 enheder. Såfremt brugeren ønsker det kan han lave denne pris til en variabel og bruge den i andre priser. Lad os sige at brugeren kalder prisen "vejl_udsalg"

Herefter kan brugeren så oprette en ny pris v. ex. 5 enheder. Dette kunne være "vejl_udsalg*0.85".

På den måde vil rabatten altid tilrette sig efter vejl_udsalg.

Ved godt ovenstående eksempel kunne gøres med en simpel "rabat_i_procent" kolonne. Men dette setup kan bruges til mange andre kombinationer.

udover selv at kunne oprette variabler bliver der også konstanter der kan bruges eksempel.

varens kostpris = cost
varens kostpris + fragt + handling = cost+
Avatar billede repox Seniormester
21. december 2010 - 12:29 #8
Jeg tror du har ret i at det er rimelig kringlet ;) Jeg har ikke nogen umiddelbar løsning på dit problem - min første indskydelse ville være at lave regelsæt for specifikke udregningsmetoder.

Altså, specifikation af de tilgængelige udregninger, istedet for at lade folk selv finde på dem.

Sammensæt tallene i et array, som du gemmer i databasen og hiver ud og anvender i den specifikke/tilgængelige funktion som kan beregne det du efterlyser.

F.eks.:

function rabat_i_procent($arrayData)
{
  $result = $arrayData["vejl_udsalg"] * $arrayData["rabat_sats"];
  return $result;
}

...

$sql = "SELECT arrayData FROM rabatTable WHERE rId = 3";
$res = mysql_query($sql);
$arrayData = unserialize(mysql_result($res, 0, $arrayData));

//$arrayData kan så indeholde mange andre prædefinerede satser og tal.
$arrayData["vejl_udsalg"] = $den_vejledende_udsalgs_pris_du_vil_regne_paa;

$func = $arrayData["regne_funktion"]; //som kunne indeholde "rabat_i_procent"
$func($arrayData);
Avatar billede groyk Novice
21. december 2010 - 12:59 #9
Hej repox

Det er sådan vores gamle system fungere. Dette giver os dog nogle begrænsninger. Jeg arbejder videre på løsningen.

Hvis jeg skal lave en regex der KUN tillader tal fra 0-9 samt .-+/()

Er det noget du er skarp til?
Avatar billede repox Seniormester
21. december 2010 - 13:07 #10
Mjaeh, det ville være noget ala:
^[0-9\+\-\/\*\(\)]+$
Avatar billede groyk Novice
21. december 2010 - 13:30 #11
Takker for hjælpen.

Smider du lige et svar?
Avatar billede repox Seniormester
21. december 2010 - 13:39 #12
Du fik et svar her
Avatar billede groyk Novice
24. december 2010 - 14:26 #13
Hej repox

Ud fra din regex har jeg arbejdet lidt videre.

Har lavet to regex'er der validere stringen.

Har lavet et lille test script til forskellige kombinationer.

Dog ville det være cool hvis det kunne smeltes ind i en regex.


<?

$equation[] ='/1+2)';
$equation[] ='(1+2)';
$equation[] ='(1/2)';
$equation[] ='(1+2)/';
$equation[] ='(1+2)+';
$equation[] ='(1+2)-';
$equation[] ='(1+(2(';
$equation[] ='(1+2)/';
$equation[] ='(1/+2)';
$equation[] ='+(1+2)';
$equation[] ='/(1+2)';
$equation[] ='-(1+2)';
$equation[] ='(-1+2)';
$equation[] ='(-1+2)';

function evaluate_equation($equation)
{
    $error = 0;
    if(!preg_match("/^[^\/\)][0-9\+\-\/\*\(\)]+[^\(\/\-\+]$/",$equation))
        $error = 1;
       
    if(preg_match("/([\+\-\*\/][\+\-\/\*\)]|[\(][\*\/\)])/",$equation))
        $error = 1;
       
    if($error==0)
        echo "$equation - OK<br />";
    else
        echo "$equation - FAIL<br />";
}

foreach($equation as $e)
    evaluate_equation($e);

?>
Avatar billede groyk Novice
25. december 2010 - 14:43 #14
Fik lige 30 minutters frihed.

Her er en endelig funktion der validere om en string kan beregnes.


function evaluate_equation($equation)
{
   
    if(preg_match("/(^[^\/\)][0-9\+\-\/\*\(\)]+[^\(\/\-\+]$)|^([\+\-\*\/][\+\-\/\*\)]|[\(][\*\/\)])/",$equation) AND substr_count($equation, '(')==substr_count($equation, ')'))
        eval("\$equation = $equation;");
    else
        $equation = 'Equation failed.';
       
    return $equation;
}
Avatar billede groyk Novice
25. december 2010 - 15:12 #15
Hmm. stadig fejl

Ken ikke lige hitte ud af at sætte de to regex sammen.

Så jeg endte om med følgende funktion


function valid_equation($equation)
    {
        if(preg_match("/^[^\/\)][0-9\+\-\/\*\(\)]+[^\(\/\-\+]$/",$equation) AND !preg_match("/[\+\-\*\/][\+\-\/\*\)]|[\(][\*\/\)]/",$equation) AND substr_count($equation, '(')==substr_count($equation, ')'))
            eval("\$equation = $equation;");
        else
            $equation = 'Equation failed.';
       
        return $equation;
    }
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester