代码之家  ›  专栏  ›  技术社区  ›  animuson Hemanshu

如何在PHP中首先处理最大的匹配?

  •  0
  • animuson Hemanshu  · 技术社区  · 14 年前

    好的,所以我试着先四处搜索,但我不知道这个问题或搜索短语该怎么说。让我解释一下。

    <!-- data:start -->
        <!-- 0:start -->
            <!-- 0:start -->0,9<!-- 0:stop -->
            <!-- 1:start -->0,0<!-- 1:stop -->
            <!-- 2:start -->9,0<!-- 2:stop -->
            <!-- 3:start -->9,9<!-- 3:stop -->
            <!-- 4:start -->0,9<!-- 4:stop -->
        <!-- 0:stop -->
        <!-- 1:start -->
            <!-- 0:start -->1,5<!-- 0:stop -->
            <!-- 1:start -->1,6<!-- 1:stop -->
            <!-- 2:start -->3,6<!-- 2:stop -->
            <!-- 3:start -->3,8<!-- 3:stop -->
            <!-- 4:start -->4,8<!-- 4:stop -->
        <!-- 1:stop -->
        <!-- 2:start -->
            <!-- 0:start -->0,7<!-- 0:stop -->
            <!-- 1:start -->1,7<!-- 1:stop -->
        <!-- 2:stop -->
    <!-- data:stop -->
    

    所以基本上是一堆点。下面是我当前用来尝试解析它的代码,以便它创建如下数组:

    Array (
        0 => Array (
            0 => "0,9",
            1 => "0,0",
            2 => "9,0",
            3 => "9,9",
            4 => "0,9"
        ),
        1 => Array (
            0 => "1,5",
            1 => "1,6",
            2 => "3,6",
            3 => "3,8",
            4 => "4,8"
        ),
        2 => Array (
            0 => "0,7",
            1 => "1,7"
        )
    )
    

    Array (
        0 => "0,9",
        1 => "0,0",
        2 => "9,0"
    )
    

    查看屏幕上较大的数组,您会看到它正在设置匹配时该变量的第一个实例。那么我如何让它先找到最宽的匹配,然后处理内部。以下是我当前使用的函数:

    function explosion($text) {
        $number = preg_match_all("/(<!-- ([\w]+):start -->)\n?(.*?)\n?(<!-- \\2:stop -->)/s", $text, $matches, PREG_SET_ORDER);
        if ($number == 0) return $text;
        else unset($item);
        foreach ($matches as $item) if (empty($data[$item[2]])) $data[$item[2]] = $this->explosion($item[3]);
        return $data;
    }
    

    这是一个 full output log 我从中提取这个样本的整个数据集。标签打印出来(替换为>和<)一切都在一个巨人体内 <code></code>

    下面是搞乱的部分:

    Array ( [0] => <!-- 0:start --> <!-- 0:start -->0,9<!-- 0:stop -->  [1] => 0 [2] => <!-- 0:start -->0,9 )
    
    0 => <!-- 0:start -->0,9
    

    所以它在第一次出现停止标签的时候就停止了。我是否应该反方向思考,先处理最小的零件,替换它们,这样就不会打断较大的零件,然后再处理较大的零件?

    2 回复  |  直到 14 年前
        1
  •  2
  •   pars    14 年前

    function explosion($text) {
        preg_match_all("/<!-- ([\d]+):start -->(.+?)<!-- .*:stop -->/", $text, $matches, PREG_SET_ORDER);
    
        $return = array();
        foreach($matches as $match) {
            if($match[1]==0) {
                $return[] = array();
            }
            $return[count($return)-1][] = $match[2];
        }   
        return $return;
    }
    
        2
  •  1
  •   pinaki    14 年前

    function explosion($text) {
        $number = preg_match_all('/<(.*?)>(.+?)[<]/s', $text, $matches);
        if ($number == 0) return $text;
    
        $temp = array();
        $data = array();
        foreach($matches[2] as $coords){
            if(trim($coords)==""){
                if(!empty($temp)){
                    $data[] = $temp;
                    $temp = array();
                }
            }else{
                $temp[] = $coords;
            }
        }
        return $data;
    }
    

    您的代码的问题是它拾取子标记和标记值。当然,当它在浏览器中打印时会被隐藏,所以试着把它记录下来以便调试。