PHP regex,preg_replace_callback,在1个字符串中失败,有2个可能的匹配

Maa*_*per 5 php regex preg-replace

我正在玩这个非常基础的课程,以了解有关正则表达式的更多信息.我想要实现的是从testview文件中获取内容,在{{EACH slides}}和{{#EACH}}之间准确抓取字符串.现在在类中出现的正则表达式就是这样,加上开始标记中的变量名.然后我想使用该字符串用正确的变量循环它并将其放回原位.

但是当我在视图中使用2个EACH循环而不是1时,它会严重失败.preg_replace_callback()将匹配第一个开始标记和第二个循环的最后一个结束标记,并给出如下字符串:

"htmlbalalbal {{#EACH}} more htmlblabla {{EACH newsitems}} htmlblalblabla"
Run Code Online (Sandbox Code Playgroud)

从:

<div class="rows-container">
{{each slides}}
    <div class="row flex-wrap" data-id="{{id}}">
    </div>
{{#each}}
</div>
<div class="rows-container">
{{each blogposts}}
    <div class="row flex-wrap" data-id="{{id}}">
    </div>
{{#each}}
Run Code Online (Sandbox Code Playgroud)

我一直在尝试改变正则表达式一段时间了,我开始看到越来越多的逻辑......但我还没有解决我的问题.是否有可能走这条路?或者我是否需要另一种解决方案来扫描我的测试文件中的多个EACH循环?我可能很快会使用一些框架,但是当我在周末感到无聊时,我喜欢这样做...

class Aclass{

    private $each = '~\{\{each ([^{]*)\}\}([^*]*)\{\{\#each\}\}~i';

    private $current_file_content = "";
    private $testviews = ['/testview.php'];

    private $views;

    function __construct($views){
        $this->views = $views; //not in use
        $this->start();
   }

   private function start(){
        foreach($this->testviews as $file){
            $this->current_file_content = file_get_contents(ROOT.$file);
            $this->scan_each();
        }
   }

   private function scan_each(){
       $result = preg_replace_callback($this->each, [$this, '_each'], $this->current_file_content);
   }


    private function _each($matches){
        foreach($matches as $match){
            var_dump(htmlspecialchars($match));
            echo '<br><br>';
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑:16-5所以,我一直在进一步..它的工作很好,但它并没有覆盖每个内部的每一个.这是一种类似的情况,我认为将来可能会有用:

{{each attributes}}
<label>{title}</label>
<select name="{key}" id="{key}" class="select">
    <option value="0" selected>choose an option</option>
    {{each values}}
        <option value="{id}" {selected}>{title}</option>
    {{#each}}
</select>
{{#each}}
Run Code Online (Sandbox Code Playgroud)

我一直在想是否有办法在1个正则表达式中覆盖它,然后如果处理外部每个循环的函数看到每个内部的另一个,它将首先完成该1.我完全愿意自己构建这些功能,但获得一些技巧会很棒.你会建议分离正则表达式吗?找到{{each X}}和{{#each}}并在php中以另一种方式修复它,或修复已回答的Regex以便能够处理这个问题?

Wik*_*żew 3

您的正则表达式可以修复为

'~{{each\s+([^{}]*)}}(.*?){{#each}}~is'
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示

这里的要点是,[^*]您在模式中使用的匹配任何字符,但*同时您需要匹配一个字符串和另一个字符串之间的任何 0+ 个字符。可以用.*?ands修饰符来实现。

细节

  • {{each- 文字子串
  • \s+- 1+ 空格
  • ([^{}]*)- 第 1 组:除 和 之外的零个或多个{字符}
  • }}- 文字子}}
  • (.*?) - 第 2 组:任何 0+ 个字符,尽可能少(由于惰性*?量词
  • {{#each}}- 文字子{{#each}}串。