2009-11-23 2 views
1

je dois analyser une chaîne à deux variables selon les règles suivantes, et je suis à la recherche de la meilleure façon d'y parvenir en PHP:chaîne contenant Parse plage de valeurs min et max des variables v2

"40.3" -> minval=40.3, maxval=40.3 
"-40.3" -> minval=-40.3, maxval=-40.3 
"40.3-60.76" -> minval=40.3, maxval=60.76 
"-40.3-60.76" -> minval=-40.3, maxval=60.76 
"-60.76--40.3" -> minval=-60.76, maxval=-40.3 

Malheureusement, je dois utiliser moins les deux pour les valeurs négatives, ainsi que le séparateur de distance.

Ceci est assez similaire à ma question précédente: (.. Je l'ai déjà une fois affiché cette deuxième question, mais a remarqué que j'avais sali la table un peu de chance, il va bien maintenant)

Parse string containing range of values to min and max variables

+0

Est-ce que "-40.3" est aussi là? – xtofl

+0

oui, c'est aussi acceptable – tputkonen

Répondre

5

Comme Bien que j'essaie d'éviter les expressions régulières, j'en utiliserais une dans ce cas. Je pense que cela doit correspondre à toutes vos cordes:

preg_match('/^(?P<min>-?\d+(\.\d+)?)(-(?P<max>-?\d+(\.\d+)?))?/', $string, $matches); 
$min = $matches['min']; 
if (isset($matches['max'])) { 
    $max = $matches['max']; 
} 

(La longueur de l'expression régulière est une bonne raison de les éviter dans le codage au jour le jour)

1
$test = array(
    "40.3", 
    "-544", 
    "40.3-60", 
    "-40.1234-60.76", 
    "-60.76--40.3", 

); 

$num = "(-?\d+(?:\.\d+)?)"; 
$re = "~^$num-?$num?$~"; 
foreach($test as $test) { 
    if(preg_match($re, $test, $m)){ 
     if(!isset($m[2])) $m[2] = $m[1]; 
     echo "from $m[1] to $m[2]\n"; 
    } 
} 
1

Cela a fonctionné assez bien un test:

<?php 
preg_match("/^(\-{0,1}[0-9\.])\-{0,1}(\-{0,1}[0-9\.]*)\$/", "-1-2", $matches); 
$min = $matches[1]; 
$max = $matches[2] ? $matches[2] : $min; 
?> 
2

si vous ne voulez pas utiliser des expressions régulières, cette fonction fera:

function parse_range($range) { 
    list($from, $to) = explode('-', substr($range, 1), 2); 
    $from = $range[0] . $from; 
    if (!$to and $to !== '0') { 
     $to = $from; 
    } 
    return array($from * 1, $to * 1); 
} 
5

Lorsque vous rencontrez un problème, vous pouvez essayer de l'exprimer dans une sorte de forme Backus-Naur:

Range := Number | Number "-" Number 
Number := Sign Digits 
Sign := "" | "-" 
Digits := Digit* | Digit* "." Digit* 

Et créer une expression régulière de cela.

+0

c'est une bonne idée pour s'attaquer à des regex non-triviales, et il y a beaucoup de gens qui diraient que toutes les regex sont non triviales! +1 – nickf

+0

+1 parce que j'adore les BNF :) – krcko

Questions connexes