猿问

将文件名与通配符匹配时,正则表达式无法按预期工作

我正在编写一个 PHP 函数,它接受一个文件名数组,如果文件名与用户输入的一组条件不匹配,则从该数组中删除文件名。该函数遍历数组并将每个值与正则表达式进行比较。正则表达式是通过插入来自用户输入的变量而形成的。如果用户没有指定变量,则在变量的位置插入正则表达式通配符。文件名都非常系统化,所以2020-06-N-1.txt我确切地知道文件名和用户输入中预期有多少个字符。但是,当我运行代码时,与正则表达式不匹配的文件名仍在数组中。删除了一些不匹配的文件名,但保留了许多其他文件名。下面是我的部分 PHP 代码。任何帮助表示赞赏。


function fileFilter() {

    global $fileArray, $fileFilterPattern;

    

    /* The loop starts at 2 and goes to count()-1 because the first 2 elements were removed 

earlier with unset */

    for ($j = 2; $j < count($fileArray) - 1; $j++) {

        if(!(preg_match($fileFilterPattern, $fileArray[$j]))) {

            unset($fileArray[$j]);

        }

    }

    return;

}


// If user does not provide a filter value, it gets converted into wildcard symbol

if ($month == '') {

    $month = '..';

}

if ($year == '') {

    $year = '....';

}

if ($section == '') {

    $section = '.';

}


$fileFilterPattern = "/{$year}-{$month}-{$section}-.\.txt/";


/* function only runs if user applied at least one filter */

if (!($month == '..' && $year == '....' && $section == '.')) {

    fileFilter();

}

下面我提供了一个示例,说明数组如何包含不匹配的元素。我使用我的输出数组echo json_encode($fileArray);


我的输入:

月是"" 年是""

节是"L"


预期结果:

数组仅包含在部分 spot ( YEAR-MONTH-**SECTION**-NUMBER.txt)中具有 L 的文件


结果数组:


{"8":"2020-06-L-1.txt","9":"2020-06-L-2.txt","10":"2020-06-L-3.txt","11":"2020-06-L-4.txt","12":"2020-06-L-5.txt","15":"2020-06-N-3.txt","16":"2020-06-N-4.txt","17":"2020-06-N-5.txt","18":"2020-06-N-6.txt","19":"2020-06-O-1.txt","20":"2020-06-O-2.txt","21":"2020-06-O-3.txt","22":"2020-06-O-4.txt","23":"2020-06-S-1.txt","24":"2020-06-S-2.txt","25":"2020-06-S-3.txt"}


一只斗牛犬
浏览 210回答 2
2回答

喵喵时光机

问题是在循环中使用 unset() 。在下一次迭代中,索引不再与您使用 unset() 破坏数组之前的索引相同。有时,您可以使用 array_values() 来处理这个问题,但在这种情况下,只构建第二个仅包含您想要的值的数组会更简单。以下代码有效。我使用 array_values() 只是为了获取您提供的字符串并使索引恢复正常。也就是说,由于“前 2 个元素之前已使用 unset 删除”,因此您需要在到达此部分之前对数组运行 array_values() 。<?php$str ='{"8":"2020-06-L-1.txt","9":"2020-06-L-2.txt","10":"2020-06-L-3.txt","11":"2020-06-L-4.txt","12":"2020-06-L-5.txt","15":"2020-06-N-3.txt","16":"2020-06-N-4.txt","17":"2020-06-N-5.txt","18":"2020-06-N-6.txt","19":"2020-06-O-1.txt","20":"2020-06-O-2.txt","21":"2020-06-O-3.txt","22":"2020-06-O-4.txt","23":"2020-06-S-1.txt","24":"2020-06-S-2.txt","25":"2020-06-S-3.txt"}';$fileArray = json_decode($str, true);$fileArray = array_values($fileArray);echo '<p>fileArray: ';var_dump($fileArray);echo '</p>';function fileFilter() {&nbsp; &nbsp; global $fileArray, $fileFilterPattern;&nbsp; &nbsp; $filteredArray = [];&nbsp; &nbsp; for ($j = 0; $j < count($fileArray); $j++) {&nbsp; &nbsp; &nbsp; &nbsp; if(preg_match($fileFilterPattern, $fileArray[$j]) === 1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //unset($fileArray[$j]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; array_push($filteredArray, $fileArray[$j]);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; echo '<p>filteredArray: ';&nbsp; &nbsp; var_dump($filteredArray);&nbsp; &nbsp; echo '</p>';&nbsp; &nbsp; //return;}$month =='';$year = '';// If user does not provide a filter value, it gets converted into wildcard symbolif ($month == '') {&nbsp; &nbsp; $month = '..';}if ($year == '') {&nbsp; &nbsp; $year = '....';}if ($section == '') {&nbsp; &nbsp; $section = '.';}$section = 'L';$fileFilterPattern = "#{$year}-{$month}-{$section}-.\.txt#";echo '<p>fileFilterPattern: ';var_dump($fileFilterPattern);echo '</p>';/* function only runs if user applied at least one filter */if (!($month == '..' && $year == '....' && $section == '.')) {&nbsp; &nbsp; fileFilter();}?>

慕桂英546537

主要问题是count每次减少unset,所以你应该定义一次计数。假设-1和$j = 2对于您的场景是正确的:$count = count($fileArray) - 1;for ($j = 2; $j < $count; $j++) {&nbsp; &nbsp; if(!(preg_match($fileFilterPattern, $fileArray[$j]))) {&nbsp; &nbsp; &nbsp; &nbsp; unset($fileArray[$j]);&nbsp; &nbsp; }}还有其他方法,您不必假设然后跟踪密钥:foreach($fileArray as $k => $v) {&nbsp; &nbsp; if(!preg_match($fileFilterPattern, $v)) {&nbsp; &nbsp; &nbsp; &nbsp; unset($fileArray[$k]);&nbsp; &nbsp; }}我会摆脱你的fileFilter功能并改用这个方便的功能,它将返回与模式匹配的所有项目:$fileArray = preg_grep($fileFilterPattern, $fileArray);
随时随地看视频慕课网APP
我要回答