Parse string containing range of values to min and max variables
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, maxag开发者_开发知识库e=40
"-40" -> minage=null, maxage=40
"40-" -> minage=40, maxage=null
"40-60" -> minage=40, maxage=60
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;
}
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.
$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]);
}
Here is a solution that will correctly handle 0 values in the range expression with only one preg_
function call.
I'll add a helper function which will cast non-null values to an integer data type. Of course, if this casting is not critical, it can be omitted and the extracted values will be null
or string type.
Essentially, the regex makes all components in the string optional and gives priority to the max age when populating the array of matches. The hyphen is captured to determine whether the max age should be used to replace the null
min age.
The null coalescing assignment operator (??=
) means that the following condition is only executed if $minAge
is null
.
Code: (Demo)
$ranges = [
"40", // minage=40, maxage=40
"-40", // minage=null, maxage=40
"40-", // minage=40, maxage=null
"40-60", // minage=40, maxage=60
"0", // minage=0, maxage=0
"-0", // minage=null, maxage=0
"0-", // minage=0, maxage=null
"0-0"
];
function nullableInt(?int $v) { return $v; }
foreach ($ranges as $range) {
[, $minAge, $hyphen, $maxAge] = preg_match('/^(\d+)??(-)?(\d+)?$/', $range, $m, PREG_UNMATCHED_AS_NULL) ? $m : [null, null, null, null];
$minAge ??= ($hyphen ? null : $maxAge);
var_export(['minAge' => nullableInt($minAge), 'maxAge' => nullableInt($maxAge)]);
echo "\n";
}
Output:
array (
'minAge' => 40,
'maxAge' => 40,
)
array (
'minAge' => NULL,
'maxAge' => 40,
)
array (
'minAge' => 40,
'maxAge' => NULL,
)
array (
'minAge' => 40,
'maxAge' => 60,
)
array (
'minAge' => 0,
'maxAge' => 0,
)
array (
'minAge' => NULL,
'maxAge' => 0,
)
array (
'minAge' => 0,
'maxAge' => NULL,
)
array (
'minAge' => 0,
'maxAge' => 0,
)
精彩评论