【问题标题】:how to use markdown parsing technique in php to make separate automated process如何在php中使用markdown解析技术来制作单独的自动化进程
【发布时间】:2026-01-31 16:00:01
【问题描述】:

我想开发一个带有轻微自动化过程的网站,或者使用markdown技术的页眉、菜单、导航栏、页脚等。

例如,navigationbar.md 将只包含链接文本和链接地址,我想将这些详细信息(链接和文本,没有解析的 html 格式)单独获取到 php 中的变量或参数中。

* [Dog][0]
* [German Shepherd][1]
* [Belgian Shepherd][2]
    * [Malinois][3]
    * [Groenendael][4]
    * [Tervuren][5]
* [Cat][6]
    * [Siberian][7]
    * [Siamese][8]

[0]:(http://google.com)
[1]:(http://google.com)
[2]:(http://google.com)
[3]:(http://google.com)
[4]:(http://google.com)
[5]:(http://google.com)
[6]:(http://google.com)
[7]:(http://google.com)
[8]:(http://google.com)

如果这里不需要任何 html id 希望嵌套数组包含链接文本和链接地址

markdown 的这种结构将创建如下的 html 输出

但我需要将这些列表作为嵌套数组来执行定义的任务。

让我知道这是否有效..他们有机会吗

预期输出

      array (size=9)
      0 => 
        array (size=2)
          0 => string 'Dog' (length=3)
          1 => string 'http://google.com' (length=17)
      1 => 
        array (size=2)
          0 => string 'German Shepherd' (length=15)
          1 => string 'http://yahoo.com' (length=16)
      2 => 
        array (size=2)
          0 => string 'Belgian Shepherd' (length=16)
          1 => string 'http://duckduckgo.com' (length=21)
          2 => 
            array (size=2)
              0 => string 'Malinois' (length=8)
              1 => string 'http://amazon.com' (length=17)
              2 => 
                array (size=2)
                  0 => string 'Groenendael' (length=11)
                  1 => string 'http://metallica.com' (length=20)
              3 => 
                array (size=2)
                  0 => string 'Tervuren' (length=8)
                  1 => string 'http://microsoft.com' (length=20)
      3 => 
        array (size=2)
          0 => string 'Cat' (length=3)
          1 => string 'http://ibm.com' (length=14)
          2 => 
            array (size=2)
              0 => string 'Siberian' (length=8)
              1 => string 'http://apple.com' (length=16)
          3 => 
            array (size=2)
              0 => string 'Siamese' (length=7)
              1 => string 'http://*.com' (length=24)

【问题讨论】:

    标签: php html markdown r-markdown


    【解决方案1】:

    这应该可行。我已经在代码中的 cmets 中提供了所有解释。这行得通 -

    /**
        This function takes a strings- $text and $links_text.
        For each text value that matches the regular expression, the link
        from the $links_text is extracted and given as output.
        This returns an array consisting of the text mapped to their links.
        It will return a single array if there only single text value, and 
        a nested array if more than one text is found.
        Eg: 
        INPUT:
            var_dump(text_link_map("* [Dog][0]", "[0]:(http://google.com)[1]:(http://yahoo.com)"));
        OUTPUT: 
            array
              0 => string 'Dog' (length=3)
              1 => string 'http://google.com' (length=17)
    */
    function text_link_map($text, $links_text){
        $regex= "/\*\s+\[([a-zA-Z0-9\-\_ ]+)\]\[([0-9]+)\]/";
        if(preg_match_all($regex, $text, $matches)){
            $link_arr = Array();
            /*
                For each of those indices, find the appropriate link.
            */
            foreach($matches[2] as $link_index){
                $links = Array();
                $link_regex = "/\[".$link_index."\]\:\((.*?)\)/";
                if(preg_match($link_regex,$links_text,$links)){
                    $link_arr[] = $links[1];
                }
            }
            if(count($matches[1]) == 1){
                return Array($matches[1][0], $link_arr[0]);
            }else{
                $text_link = array_map(null, $matches[1], $link_arr);
                return $text_link;
            }
        }else{
            return null;
        }
    }
    
    /**
        Function that calls recursive index, and returns it's output.
        This is is needed to pass initial values to recursive_index.
    */
    function indent_text($text_lines, $links){
        $i = 0;
        return recursive_index($i, 0, $text_lines, $links);
    }
    
    
    /**
        This function creates a nested array out of the $text.
        Each indent is assumed to be a single Tab.It is dictated by the
        $indent_symbol variable.
        This function recursively calls itself when it needs to go from 
        one level to another.
    */
    function recursive_index(&$index, $curr_level, $text, $links){
        $indent_symbol = "\t";
        $result = Array();
        while($index < count($text)){
            $line = $text[$index];
            $level = strspn($line, $indent_symbol);
            if($level == $curr_level){
                $result[] = text_link_map($line, $links);
            }elseif($level > $curr_level){
                $result[count($result) - 1][] = recursive_index($index, $curr_level + 1, $text, $links);
                if($index > count($text)){
                    break;
                }else{
                    $index--;
                }               
            }elseif($level < $curr_level){
                break;
            }
            $index += 1;
        }
        return $result;
    }   
    
    $file_name = "navigationbar.md";
    $f_contents = file_get_contents($file_name);
    //Separate out the text and links part.
    //(Assuming the text and the links will always be separated with 2 \r\n)
    list($text, $links) = explode("\r\n\r\n", $f_contents);
    //Get the nested array.
    $formatted_arr = indent_text(explode("\r\n", $text), $links);
    var_dump($formatted_arr);
    

    这是代码的输出。它符合您的要求 -

    /*
        OUTPUT
    */
    array(4) {
      [0]=>
      array(2) {
        [0]=>
        string(3) "Dog"
        [1]=>
        string(17) "http://google.com"
      }
      [1]=>
      array(2) {
        [0]=>
        string(15) "German Shepherd"
        [1]=>
        string(16) "http://yahoo.com"
      }
      [2]=>
      array(3) {
        [0]=>
        string(16) "Belgian Shepherd"
        [1]=>
        string(21) "http://duckduckgo.com"
        [2]=>
        array(3) {
          [0]=>
          array(2) {
            [0]=>
            string(8) "Malinois"
            [1]=>
            string(17) "http://amazon.com"
          }
          [1]=>
          array(2) {
            [0]=>
            string(11) "Groenendael"
            [1]=>
            string(20) "http://metallica.com"
          }
          [2]=>
          array(2) {
            [0]=>
            string(8) "Tervuren"
            [1]=>
            string(20) "http://microsoft.com"
          }
        }
      }
      [3]=>
      array(3) {
        [0]=>
        string(3) "Cat"
        [1]=>
        string(14) "http://ibm.com"
        [2]=>
        array(2) {
          [0]=>
          array(2) {
            [0]=>
            string(8) "Siberian"
            [1]=>
            string(16) "http://apple.com"
          }
          [1]=>
          array(2) {
            [0]=>
            string(7) "Siamese"
            [1]=>
            string(24) "http://*.com"
          }
        }
      }
    }
    

    检查,navigationbar.md 的内容是 -

    * [Dog][0]
    * [German Shepherd][1]
    * [Belgian Shepherd][2]
        * [Malinois][3]
        * [Groenendael][4]
        * [Tervuren][5]
    * [Cat][6]
        * [Siberian][7]
        * [Siamese][8]
    
    [0]:(http://google.com)
    [1]:(http://yahoo.com)
    [2]:(http://duckduckgo.com)
    [3]:(http://amazon.com)
    [4]:(http://metallica.com)
    [5]:(http://microsoft.com)
    [6]:(http://ibm.com)
    [7]:(http://apple.com)
    [8]:(http://*.com)
    

    代码中的某些假设 -

    • 假定分隔文本的部分(即“* [Dog][0]”部分)和链接部分(即“[0]:(http://google.com)”)始终为 用 2 个换行符分隔。
    • 每个父子节点都有一个 Tab("\t")。

    您可以通过更改 navigationbar.md 中文本之间的选项卡来进行测试。

    希望对你有帮助。

    【讨论】:

    • 谢谢你它的工作几乎和我想象的一样,但期望嵌套数组..我会编辑它..然后我会接受 anwwer..
    • 不,我的意思是嵌套数组是“比利时牧羊犬”包含 [“Malinois”,“Groenendael”,“Tervuren”],我的意思是像一个包含父项及其子项的列表.. @Yeah跨度>
    • 哦...好的,那么您打算如何映射链接?
    • 我添加了有问题的预期输出.. @Yeah
    • @ChandanPasunoori 在 navigationbar.md 中确保父子级使用制表符而不是空格来缩进。