在PHP中按正则表达式组排序

obj*_*sea 0 php regex sorting

我有一个这种形式的文件名数组:

"A - 1.2 - 平面图.PDF"

我需要首先按照开头的类别对数组进行排序,顺序如下:

1. Category: A
2. Category: ESC
3. Category: C
4. Category: M
5. Category: E
6. Category: P
Run Code Online (Sandbox Code Playgroud)

然后我需要按类别后面的数字对数组进行排序.

这是要排序的数组的示例:

$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";
Run Code Online (Sandbox Code Playgroud)

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

$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";
Run Code Online (Sandbox Code Playgroud)

我有以下正则表达式来正确分组文件名:

^([A-Z]+?) ?- ?([0-9]+)\.([0-9]+)(\.([0-9]+))?.*$
Run Code Online (Sandbox Code Playgroud)

我希望数组按组1排序,然后按组2排序,然后按组3排序.如果组5存在,则按组排序.忽略组4.

按字典顺序对类别进行排序可能更容易.如果是这样,那就没问题; 虽然如果它们按照上述顺序排序会更好.

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

Krz*_*tof 5

有一个sort函数,它将compare方法作为参数.您可以使用它,例如:

$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");
Run Code Online (Sandbox Code Playgroud)