PHP正则表达式,preg_replace_回调,失败,1个字符串中有2个可能的匹配项

PHP正则表达式,preg_replace_回调,失败,1个字符串中有2个可能的匹配项,php,regex,preg-replace,Php,Regex,Preg Replace,我在玩这个非常基本的类来学习更多关于正则表达式的知识。我想要实现的是从testview文件中获取内容,精确地获取{{EACH slides}}和{{{EACH}}之间的字符串。现在类中的正则表达式就是这样做的,加上开始标记中的变量名。然后,我想使用该字符串将其与正确的变量循环,并将其放回原位 但是当我在视图中使用2个循环而不是1个循环时,它会严重失败。 preg_replace_callback()将匹配第二个循环的第一个开始标记和最后一个结束标记,并给出如下字符串: "htmlbalalbal

我在玩这个非常基本的类来学习更多关于正则表达式的知识。我想要实现的是从testview文件中获取内容,精确地获取{{EACH slides}}和{{{EACH}}之间的字符串。现在类中的正则表达式就是这样做的,加上开始标记中的变量名。然后,我想使用该字符串将其与正确的变量循环,并将其放回原位

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

"htmlbalalbal {{#EACH}} more htmlblabla {{EACH newsitems}} htmlblalblabla"
发件人:

<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}}

{{每张幻灯片}}
{{{#各}
{{each blogposts}}
{{{#各}

我已经尝试了很长一段时间的正则表达式的改变,我开始看到越来越多的逻辑。。。但我还没有解决我的问题。甚至有可能走这条路吗?或者我需要另一个解决方案来扫描测试文件中的多个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>';
        }
    }
类Aclass{
private$each='~\{{each([^{]*)\}}([^*]*)\{{\\\\}~i';
私有$current_file_content=“”;
私有$testviews=['/testview.php'];
私人意见;
函数构造($views){
$this->views=$views;//未使用
$this->start();
}
私有函数start(){
foreach($this->testview作为$file){
$this->current_file_content=file_get_contents(ROOT.$file);
$this->scan_each();
}
}
专用函数scan_each(){
$result=preg\u replace\u回调($this->each,[$this,'.\u each'],$this->current\u file\u content);
}
私有函数(每个($matches){
foreach($matches作为$match进行匹配){
变量转储(htmlspecialchars($match));
回音“

”; } }
编辑: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}}
{{each attributes}
{title}
选择一个选项
{{each values}}
{title}
{{{#各}
{{{#各}

我一直想知道是否有一种方法可以在1个正则表达式中覆盖它,然后如果处理外部每个循环的函数在内部看到另一个,它将首先完成1。我完全愿意自己构建函数,但如果能得到一些提示,那就太棒了。你会建议分离正则表达式吗?找到{each X}和{{#each}在php中用另一种方式修复它,或者修复已应答的正则表达式以处理此问题?

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

'~{{each\s+([^{}]*)}}(.*?){{#each}}~is'

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

详细信息

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

用以下代码替换您的代码:

private$each='~{{each\s+(.+?)}}(.+?){{{{each}}}~是';


Tnx!我明天必须研究这个问题,我想在继续之前完全理解它,但它似乎有一句话:如果在
{{each
之后可能有
{
}
在最近的
}
之前,你应该用
([^{}]*)替换
([^{code>)
.Tnx!我现在已经实现了它。可以用3种类型的数组,if,else if and else,vars和superglobals来实现每种类型。但是我的模式的问题是,我不能在另一个循环中构建每个循环,每个循环中没有ifs,等等。我担心我必须将开始模式和结束模式分开,并采用不同的方式。但是对于我的学校专业版jects..如果它能工作,它就能工作lol。或者有没有一种方法可以用递归正则表达式来修复它?xD还没有研究过这个问题。