tags:

views:

59

answers:

3

I'm looking for a nice way to parse a string into two variables using PHP. The variables are called minage and maxage, and they should be parsed according to the examples below:

"40" -> minage=40, maxage=40
"-40" -> minage=null, maxage=40
"40-" -> minage=40, maxage=null
"40-60" -> minage=40, maxage=60
+4  A: 

Try this:

$minrange = null;
$maxrange = null;
$parts = explode('-', $str);
switch (count($parts)) {
case 1:
    $minrange = $maxrange = intval($parts[0]);
    break;
case 2:
    $minrange = $parts[0] == "" ? null : intval($parts[0]);
    $maxrange = $parts[1] == "" ? null : intval($parts[1]);
    break;
}
Gumbo
A: 
$parts = explode("-", $str);
$minage = NULL;
$maxage = NULL;
if (count($parts) == 1) {
  $minage = intval($parts[0]);
  $maxage = $minage;
}
else if ((count($parts) >= 2) && is_numeric($parts[0]) && is_numeric($parts[1])) {
  $minage = intval($parts[0]);
  $maxage = intval($parts[1]);
}
Dominic Rodger
+1  A: 

You could also encapsulate the data in a class, say Range:

class Range {

  protected $min;
  protected $max;

  public function __construct($str) {
    if(preg_match('/^\d+$/', $str)) {
      $this->min = (int)$str;
      $this->max = (int)$str;
    } else {
      preg_match('/^(\d*)-(\d*)$/', $str, $matches);
      $this->min = $matches[1] ? (int)$matches[1] : null;
      $this->max = $matches[2] ? (int)$matches[2] : null;
    }
  }

  // more functions here like contains($value) and/or min() and max()

  public function __toString() {
    return 'min=' . $this->min . ', max=' . $this->max;
  }
}

$tests = array('40', '-40', '40-', '40-60');
foreach($tests as $t) {
  echo new Range($t) . "\n";
}

which produces:

min=40, max=40
min=, max=40
min=40, max=
min=40, max=60

Of course, you could replace the preg_ calls with some "normal" string functions, but the only thing I know of PHP is some regex-trickery.

Bart Kiers
This is a good idea, but why make the variables protected? Presumably you want to be able to access the data you've extracted, otherwise there's no point...
Matthew Scharley
@Matthew, yes, they could be made public, or leave them protected and provide extra methods in the Range class (which I left out).
Bart Kiers