代码之家  ›  专栏  ›  技术社区  ›  Ali

使用preg_split()拆分带标记的文本

  •  -1
  • Ali  · 技术社区  · 14 年前

    我正在尝试拆分以下文本:

    <word>test</word><word>test2</word>

    通过以下注册表项:

    preg_split(":</?word>:is", $html);
    

    我得到结果: test test2 结果,但我需要的是重新培训 <word> </word> 标记,所以我得到了另外4个元素,其中包含匹配的标记,而不仅仅是test和test2。

    怎么能做到?

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

    首先:使用解析器修改XML(类似于 SimpleXML 属于 DOM 可能很适合你,取决于下一步采取的行动)。

    然而,为了争论:

    preg_split(":(</?word>):",
        "<word>test</word><word>test2</word>",
        0,
        PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
    
        2
  •  0
  •   ircmaxell    14 年前

    首先, NEVER USE REGEX TO PARSE HTML

    但要解决您的问题,请查看 preg_split()

    preg_split(
        ":(</?word>):is", 
        $html, 
        -1, 
        PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
    );
    

    现在,它将把它们分开并给您:

    array(7) {
      [0]=>
      string(6) "<word>"
      [1]=>
      string(4) "test"
      [2]=>
      string(7) "</word>"
      [3]=>
      string(2) ", "
      [4]=>
      string(6) "<word>"
      [5]=>
      string(5) "test2"
      [6]=>
      string(7) "</word>"
    }
    

    还是不行。但是,我们可以做的是循环数组,然后移动 <word> 到下一个缓冲区,以及 </word> 以前的…

    $buffer = '';
    $newWords = array();
    foreach ($words as $word) {
        if (strcasecmp($word, '<word>') === 0) {
            $buffer .= $word;
        } elseif (strcasecmp($word, '</word>') === 0) {
            // Find the last buffer
            $last = end($newWords);
            $newWords[key($newWords)] = $last . $buffer . $word;
            $buffer = '';
        } else {
            $newWords[] = $buffer . $word;
            $buffer = '';
        }
    }
    if (!empty($buffer)) {
        $newWords[] = $buffer;
    }
    

    这会给你:

    array(3) {
      [0]=>
      string(17) "<word>test</word>"
      [1]=>
      string(2) ", "
      [2]=>
      string(18) "<word>test2</word>"
    }