按命名组大小排序preg_match_all

时间:2017-05-11 20:52:13

标签: php

我编写了一个正则表达式来解析JS文件并返回所有已命名的函数并将其分解为3个部分,您可以在此处看到它:https://regex101.com/r/sXrHLI/1

我正在分析结果并希望按functionBody的字符串长度排序,但我无法弄清楚如何去做。

以下是我捕捉它的方式:

$js = file_get_contents('scripts.js'); 
$regex = "/function\s+(?<functionName>\w+)\s*\((?<functionArguments>(?:[^()]+)*)?\s*\)\s*(?<functionBody>{(?:[^{}]+|(?-1))*+})/";
preg_match_all($regex, $js, $jsFunctions);
dd($jsFunctions);

这会吐出这样一个数组:

array(7) {
  [0]=>
  array(3) {
    [0]=>
    string(54) "function smallFunction(arg) {
    BodyofSmallFunction
}"
    [1]=>
    string(62) "function mediumFunction(arg, arg2) {
    BodyofMediumFunction
}"
    [2]=>
    string(80) "function largeFunction(arg, arg2, arg3=4) {
    BodyofLargeFunction, extra text
}"
  }
  ["functionName"]=>
  array(3) {
    [0]=>
    string(13) "smallFunction"
    [1]=>
    string(14) "mediumFunction"
    [2]=>
    string(13) "largeFunction"
  }
  [1]=>
  array(3) {
    [0]=>
    string(13) "smallFunction"
    [1]=>
    string(14) "mediumFunction"
    [2]=>
    string(13) "largeFunction"
  }
  ["functionArguments"]=>
  array(3) {
    [0]=>
    string(3) "arg"
    [1]=>
    string(9) "arg, arg2"
    [2]=>
    string(17) "arg, arg2, arg3=4"
  }
  [2]=>
  array(3) {
    [0]=>
    string(3) "arg"
    [1]=>
    string(9) "arg, arg2"
    [2]=>
    string(17) "arg, arg2, arg3=4"
  }
  ["functionBody"]=>
  array(3) {
    [0]=>
    string(26) "{
    BodyofSmallFunction
}"
    [1]=>
    string(27) "{
    BodyofMediumFunction
}"
    [2]=>
    string(38) "{
    BodyofLargeFunction, extra text
}"
  }
  [3]=>
  array(3) {
    [0]=>
    string(26) "{
    BodyofSmallFunction
}"
    [1]=>
    string(27) "{
    BodyofMediumFunction
}"
    [2]=>
    string(38) "{
    BodyofLargeFunction, extra text
}"
  }
}

现在我想按functionBody大小排序(它们已经显示排序,但实际上只是按照我的顺序排列)但是我找不到使用array_multisort或array_map的代码示例适合PHP自动构建的数组。我本来希望以更多的统一树格式使用它们,但这不是我的选择。

function sort_by_length($arrays) {
    $lengths = array_map('count', $arrays);
    asort($lengths);
    $return = array();
    foreach(array_keys($lengths) as $k)
        $return[$k] = $arrays[$k];
    return $return;
}

1 个答案:

答案 0 :(得分:1)

我能够使用此处描述的方法找出答案:https://www.codepunker.com/blog/3-solutions-for-multidimensional-array-sorting-by-child-keys-or-values-in-PHP

$js = file_get_contents('scripts.js'); 
$regex = "/function\s+(?<functionName>\w+)\s*\((?<functionArguments>(?:[^()]+)*)?\s*\)\s*(?<functionBody>{(?:[^{}]+|(?-1))*+})/";

preg_match_all($regex, $js, $jsFunctions);

$num_results = count($jsFunctions[3]);

function sortRegex(){
  global $jsFunctions, $num_results;

  for( $j=0;  $j <= $num_results; $j++){
    unset($jsFunctions[$j]);
    if ( strlen($jsFunctions["functionBody"][$j]) < strlen($jsFunctions["functionBody"][$j-1]) ){
      $functionBody = $jsFunctions["functionBody"][$j];
      $jsFunctions["functionBody"][$j] = $jsFunctions["functionBody"][$j-1];
      $jsFunctions["functionBody"][$j-1]=$functionBody;

      $functionName = $jsFunctions["functionName"][$j];
      $jsFunctions["functionName"][$j] = $jsFunctions["functionName"][$j-1];
      $jsFunctions["functionName"][$j-1]=$functionName;

      $functionArguments = $jsFunctions["functionArguments"][$j];
      $jsFunctions["functionArguments"][$j] = $jsFunctions["functionArguments"][$j-1];
      $jsFunctions["functionArguments"][$j-1]=$functionArguments;
      sortRegex();
    }
  }

}
sortRegex();

您现在可以再次循环它,并根据需要将项目组合成嵌套的树格式。

$refinedJS = array();

for( $j=0;  $j < $num_results; $j++){
$refinedJS[$j]= array(
  "functionName"=>$jsFunctions["functionName"][$j],
  "functionArguments"=>$jsFunctions["functionArguments"][$j],
  "functionBody"=>$jsFunctions["functionBody"][$j]
  );
}
print_r($refinedJS);

这会带来如下结果:

Array
(
    [0] => Array
        (
            [functionName] => smallFunction
            [functionArguments] => arg
            [functionBody] => {
    BodyofSmallFunction
}
        )

    [1] => Array
        (
            [functionName] => mediumFunction
            [functionArguments] => arg, arg2
            [functionBody] => {
    BodyofMediumFunction
}
        )

    [2] => Array
        (
            [functionName] => largeFunction
            [functionArguments] => arg, arg2, arg3=4
            [functionBody] => {
    BodyofLargeFunction, extra text
}
        )

)