2011-12-09 55 views
0

排序我有这种形式的文件名的数组:通过正则表达式组在PHP

“A - 1.2 - 地板Plan.PDF”

我需要阵列通过在开始第一类排序,按以下顺序:

1. Category: A 
2. Category: ESC 
3. Category: C 
4. Category: M 
5. Category: E 
6. Category: P 

然后,我需要按类别后的数字排序数组。

这里是要排序的数组的一个例子:

$arr[0] = "A - 1.0 - Title Page.PDF"; 
$arr[1] = "A - 2.2 - Enlarged Floor Plans"; 
$arr[2] = "A - 2.1.0 - Structural Details.PDF"; 
$arr[3] = "E - 1.0 - Electrical Title Page.PDF"; 
$arr[4] = "A - 1.2 - Floor Plan.PDF"; 
$arr[5] = "P - 1.0 - Plumbing Title Page.PDF"; 
$arr[6] = "A - 2.1.1 - Structural Details.PDF"; 
$arr[7] = "C - 1.0 - Civil Title Page.PDF"; 
$arr[8] = "M - 1.0 - Mechanical Title Page.PDF"; 
$arr[9] = "ESC - 1.0 - Erosion Control Plan.PDF"; 

理想的情况下,这个数组将随即成为

$arr[0] = "A - 1.0 - Title Page.PDF"; 
$arr[1] = "A - 1.2 - Floor Plan.PDF"; 
$arr[2] = "A - 2.1.0 - Structural Details.PDF"; 
$arr[3] = "A - 2.1.1 - Structural Details.PDF"; 
$arr[4] = "A - 2.2 - Enlarged Floor Plans"; 
$arr[5] = "ESC - 1.0 - Erosion Control Plan.PDF"; 
$arr[6] = "C - 1.0 - Civil Title Page.PDF"; 
$arr[7] = "M - 1.0 - Mechanical Title Page.PDF"; 
$arr[8] = "E - 1.0 - Electrical Title Page.PDF"; 
$arr[9] = "P - 1.0 - Plumbing Title Page.PDF"; 

我有一个适当的分组中的文件名下面的正则表达式:

^([A-Z]+?) ?- ?([0-9]+)\.([0-9]+)(\.([0-9]+))?.*$ 

我想按组1排序的数组,然后按组2,然后按组3 。如果第5组存在,则最后按组5排序。忽略组4.

按字典顺序排列类别可能更容易。如果是这样,那就没事了;但如果按照上述顺序排序,则更为可取。

有没有办法用PHP来做到这一点?

+1

不应该是这样的顺序:'A - 1.0, A - 1.2,A - 2.1.0,A - 2.1.1,A - 2.2,C - 1.0,E - 1.0,ESC - 1.0,M - 1.0,P - 1.0' – Krzysztof

+0

@Lolo,不是吗?我比较你的排序版本和我的。我找不到区别。 – objectivesea

+0

你有:[...],** ESC,C,M,E **,[...] 我只是想知道为什么不:[...] ** C,E,ESC,M ** ,[...] – Krzysztof

回答

4

有一种以比较方法作为参数的排序函数。您可以使用它,例如像这样:

$order = array('A', 'ESC', 'C', 'M', 'E', 'P'); // order of categories 
$order = array_flip($order); // flip order array, it'll look like: ('A'=>0, 'ESC'=>1, ...) 

function cmp($a, $b) 
{ 
    global $order; 

    $ma = array(); 
    $mb = array(); 
    preg_match('/^([A-Z]+?) ?- ?([0-9]+)\.([0-9]+)(?:\.([0-9]+))?.*$/', $a, $ma); 
    preg_match('/^([A-Z]+?) ?- ?([0-9]+)\.([0-9]+)(?:\.([0-9]+))?.*$/', $b, $mb); 

    if ($ma[1] != $mb[1]) { 
     return ($order[$ma[1]] < $order[$mb[1]]) ? -1 : 1; 
    } 
    if ($ma[2] != $mb[2]) { 
     return $ma[2] < $mb[2] ? -1 : 1; 
    } 
    if ($ma[3] != $mb[3]) { 
     return $ma[3] < $mb[3] ? -1 : 1; 
    } 
    // I've changed a regex a little bit, so the last number is 4th group now 
    if (@$ma[4] != @$mb[4]) { 
     return @$ma[4] < @$mb[4] ? -1 : 1; 
    } 
    return 0; 
} 
usort($arr, "cmp"); 
1

如何:

$arr[0] = "A - 1.0 - Title Page.PDF"; 
$arr[1] = "A - 2.2 - Enlarged Floor Plans"; 
$arr[2] = "A - 2.1.0 - Structural Details.PDF"; 
$arr[3] = "E - 1.0 - Electrical Title Page.PDF"; 
$arr[4] = "A - 1.2 - Floor Plan.PDF"; 
$arr[5] = "P - 1.0 - Plumbing Title Page.PDF"; 
$arr[6] = "A - 2.1.1 - Structural Details.PDF"; 
$arr[7] = "C - 1.0 - Civil Title Page.PDF"; 
$arr[8] = "M - 1.0 - Mechanical Title Page.PDF"; 
$arr[9] = "ESC - 1.0 - Erosion Control Plan.PDF"; 


function cmp($a,$b) { 
    $arr_a = split(' - ', $a); 
    $arr_b = split(' - ', $b); 
    if ($arr_a[0] == $arr_b[0]) 
     return strcmp($arr_a[1], $arr_b[1]); 
    return strcmp($arr_a[0], $arr_b[0]); 
} 

usort($arr, "cmp"); 
print_r($arr); 

输出:

Array 
(
    [0] => A - 1.0 - Title Page.PDF 
    [1] => A - 1.2 - Floor Plan.PDF 
    [2] => A - 2.1.0 - Structural Details.PDF 
    [3] => A - 2.1.1 - Structural Details.PDF 
    [4] => A - 2.2 - Enlarged Floor Plans 
    [5] => C - 1.0 - Civil Title Page.PDF 
    [6] => E - 1.0 - Electrical Title Page.PDF 
    [7] => ESC - 1.0 - Erosion Control Plan.PDF 
    [8] => M - 1.0 - Mechanical Title Page.PDF 
    [9] => P - 1.0 - Plumbing Title Page.PDF 
)