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>

Open in new window

LVL 16
hankknightAsked:
Who is Participating?
 
Ray PaseurConnect With a Mentor Commented:
To future EE visitors who might happen upon this question, there is a simple and built-in PHP function that accomplishes this objective without the necessity of added code.
http://php.net/manual/en/function.natsort.php

To learn about the PHP sorting functions you can read the online man page here:
http://php.net/manual/en/array.sorting.php
0
 
lwadwellCommented:
What do you want to sort on?
  - 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+)(\.\w+)$/', $a, $bits);

But to depending on what you could throw at it ... the regex may need further refinement.
0
 
lwadwellCommented:
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;
}

Open in new window

0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
Ray PaseurCommented:
Please answer the question asked here:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_27848911.html#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.
0
 
Ray PaseurCommented:
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);

Open in new window

HTH, ~Ray
0
 
hankknightAuthor Commented:
natsort() does exactly what I need!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.