【问题标题】:Regex split position before and after match匹配前后的正则表达式拆分位置
【发布时间】:2016-11-02 20:47:42
【问题描述】:

我正在尝试使用 PHP preg_split 拆分包含[fbes_keep]...[/fbes_keep] 形式的标签的字符串。

我的正则表达式是(?=\[\/?fbes_(remove|keep)]) (regex101 link)

我的意见是

[fbes_keep]hello[/fbes_keep][fbes_remove]goodbye[/fbes_remove]

我使用的代码是$fragments = preg_split( '@(?=\[\/?fbes_(remove|keep)])@i', $original );

我想要的拆分是这样的:(| 字符是拆分,添加空格以提高可读性)

[fbes_keep] | hello | [/fbes_keep] | [fbes_remove] | goodbye | [/fbes_remove]

但我得到的分裂是:

[fbes_keep]hello | [/fbes_keep] | [fbes_remove]goodbye | [/fbes_remove]

我需要改变什么?

【问题讨论】:

    标签: php regex


    【解决方案1】:

    你试过$var = explode("|", $myString);吗?

    您正在尝试获取“hello”和“goodbye”值,对吧?

    【讨论】:

    • |s 不在原始版本中,它们仅在示例中用于演示目的。对不起,如果我让你感到困惑。
    • 为清晰起见进行了编辑。
    • 试试preg_match("'[fbes_keep](.*?)[/fbes_keep]'si",$result,$original);
    • 你的正则表达式,稍作修改,工作,但我将如何迭代它们?我想一次处理一个片段。 (为完整起见,修改正则表达式:(\[fbes_(?:keep|remove)])(.*?)(\[/fbes_(?:keep|remove)])
    【解决方案2】:

    preg_match_allimplode 函数使用以下方法:

    $str = '[fbes_keep]hello[/fbes_keep][fbes_remove]goodbye[/fbes_remove]';
    preg_match_all("/\[\/?[a-z_]+\]|[a-z]+\b/", $str, $matches);
    $result = implode(" | ", $matches[0]);
    
    print_r($result);
    

    输出:

    [fbes_keep] | hello | [/fbes_keep] | [fbes_remove] | goodbye | [/fbes_remove]
    

    【讨论】:

      【解决方案3】:

      使用 preg_match_all 并遍历匹配项,以便在使用结果时更有组织性和灵活性:

         $str = '[fbes_keep]hello[/fbes_keep][fbes_remove]goodbye[/fbes_remove]';
          preg_match_all('@([[][^]]*[]])([^[]*)([[]/[^]]*[]])@Ui', $str, $matches);
      
          /*
          // die('<pre>'.print_r($matches,true));
          Array
          (
              [0] => Array
                  (
                      [0] => [fbes_keep]hello[/fbes_keep]
                      [1] => [fbes_remove]goodbye[/fbes_remove]
                  )
      
              [1] => Array
                  (
                      [0] => [fbes_keep]
                      [1] => [fbes_remove]
                  )
      
              [2] => Array
                  (
                      [0] => hello
                      [1] => goodbye
                  )
      
              [3] => Array
                  (
                      [0] => [/fbes_keep]
                      [1] => [/fbes_remove]
                  )
      
          )
          */
      

      更新 1

          // how many matches you have is here
          $count_of_matches = count($matches[0]);
      
          // to answer your comment question...get the 3 parts for match group 0
          $match_group = 0; // you also have a match_group 1
          // loop over them if you like // foreach ($matches[0] as $match_group=>$full_match) {
      
          // for now, loop over the match group 0's 3 outputs
          for ($i=1; $i<4; $i++) {
            echo $matches[$i][$match_group].', ';
          }
          // [fbes_keep], hello, [/fbes_keep], 
      
          // or access them directly
          echo "{$matches[1][0]}, {$matches[2][0]}, {$matches[3][0]}";
      

      更新 2

          // here is the full, double loop grabbing all of them
          foreach ($matches[0] as $match_group=>$full_match) {
            for ($i=1; $i<4; $i++) {
              echo $matches[$i][$match_group].', ';
            }
            echo '<br>';
          }
      
          /* yielding
          [fbes_keep], hello, [/fbes_keep],
          [fbes_remove], goodbye, [/fbes_remove],
          */
      

      【讨论】:

      • 我将如何一次浏览一个片段?例如,如果我想遍历它们,循环会得到[fbes_keep]hello[/fbes_keep] 等等,一次一个。
      • 我正在用这个答案更新我的答案。
      • 您也可以使用 PREG_PATTERN_ORDER 和 php.net/preg_match_all 对所有匹配组进行分组。我假设您可能希望将所有“你好”和“再见”部分放在一起,但这实际上取决于您打算如何使用它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-12
      • 2017-01-03
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多