hankknight
asked on
PHP: Undefined offset with usort and preg_match
This does not work if the array contains special characters:
<pre><?php
$arr = Array ( 'xa0.txt', 'xa1.txt', 'xa10.txt', 'xa11.txt', 'xa12.txt', 'xa2.txt', 'xa3.txt', 'xa4.txt', 'xa5.txt', 'xa6.txt', 'xa7.txt', 'xa8.txt', 'xa9.txt');
usort($arr, 'cmp');
print_r($arr);
$arr = Array ( 'a/b/c_d-e555/xa0.txt', 'a/b/c_d-e555/xa1.txt', 'a/b/c_d-e555/xa10.txt', 'a/b/c_d-e555/xb10.txt', 'a/b/c_d-e555/xb11.txt', 'a/b/c_d-e555/xb2.txt', 'a/b/c_d-e555/xb1.txt', 'a/b/c_d-e555/xa11.txt', 'a/b/c_d-e555/xa12.txt', 'a/b/c_d-e555/xa2.txt', 'a/b/c_d-e555/xa3.txt', 'a/b/c_d-e555/xa4.txt', 'a/b/c_d-e555/xa5.txt', 'a/b/c_d-e555/xa6.txt', 'a/b/c_d-e555/xa7.txt', 'a/b/c_d-e555/xa8.txt', 'a/b/c_d-e555/xa9.txt');
usort($arr, 'cmp');
print_r($arr);
function cmp($a, $b) {
$a = zeroadd($a);
$b = zeroadd($b);
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
function zeroadd($a) {
preg_match('/^(\w+)(\d+)(\.\w+)$/', $a, $bits);
return sprintf("%s%05d%s",$bits[1],$bits[2],$bits[3]);
}
?></pre>
A slightly safer approach would to handle non-matching strings ... e.g.
function zeroadd($a) {
if ( preg_match('/^(.+)(\d+)(\.\w+)$/', $a, $bits) )
return sprintf("%s%05d%s",$bits[1],$bits[2],$bits[3]);
else
return $a;
}
Please answer the question asked here:
https://www.experts-exchange.com/questions/27848911/PHP-Sort-Array-Ascending-With-or-Without-Trailing-Zeros.html?anchorAnswerId=38353128#a38353128
What we're trying to get is a dialog that will lead us to an acceptably clear description of the input data and the outputs you want. Computer programming only does one thing: It transforms one data set into another data set. If we have fragments of the truth about the data, we are unlikely to give you anything more than fragments of an answer.
https://www.experts-exchange.com/questions/27848911/PHP-Sort-Array-Ascending-With-or-Without-Trailing-Zeros.html?anchorAnswerId=38353128#a38353128
What we're trying to get is a dialog that will lead us to an acceptably clear description of the input data and the outputs you want. Computer programming only does one thing: It transforms one data set into another data set. If we have fragments of the truth about the data, we are unlikely to give you anything more than fragments of an answer.
The output from this seems intuitively correct, but it would be better to know for sure that we had a representative test data set.
<?php // RAY_temp_hankknight.php
error_reporting(E_ALL);
echo '<pre>';
$arr = array
( 'xa0.txt'
, 'xa1.txt'
, 'xa10.txt'
, 'xa11.txt'
, 'xa12.txt'
, 'xa2.txt'
, 'xa3.txt'
, 'xa4.txt'
, 'xa5.txt'
, 'xa6.txt'
, 'xa7.txt'
, 'xa8.txt'
, 'xa9.txt'
)
;
natsort($arr);
print_r($arr);
$arr = array
( 'a/b/c_d-e555/xa0.txt'
, 'a/b/c_d-e555/xa1.txt'
, 'a/b/c_d-e555/xa10.txt'
, 'a/b/c_d-e555/xb10.txt'
, 'a/b/c_d-e555/xb11.txt'
, 'a/b/c_d-e555/xb2.txt'
, 'a/b/c_d-e555/xb1.txt'
, 'a/b/c_d-e555/xa11.txt'
, 'a/b/c_d-e555/xa12.txt'
, 'a/b/c_d-e555/xa2.txt'
, 'a/b/c_d-e555/xa3.txt'
, 'a/b/c_d-e555/xa4.txt'
, 'a/b/c_d-e555/xa5.txt'
, 'a/b/c_d-e555/xa6.txt'
, 'a/b/c_d-e555/xa7.txt'
, 'a/b/c_d-e555/xa8.txt'
, 'a/b/c_d-e555/xa9.txt'
)
;
natsort($arr);
print_r($arr);
HTH, ~Ray
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
natsort() does exactly what I need!
- the entire path and file name with name adjusted to have leading zeroes; or
- just the file name adjusted to have leading zeroes
If everything + the filename etc try the preg_match() in the zeroadd function
preg_match('/^(.+)(\d+)(\.
But to depending on what you could throw at it ... the regex may need further refinement.