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 PaseurCommented:
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
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
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.