PHP正则表达式递归匹配

PHP正则表达式递归匹配,php,regex,nested,Php,Regex,Nested,我正在尝试匹配模板文件中的一组特定标记。然而,我希望标签是正确的 能够嵌套在自身中 我的正则表达式如下:(带/s) 小组(2) y x 我想要2个匹配项,而不是1个。显然,嵌套的标记集不匹配。这在正则表达式中是可能的,还是应该保留regexing group(2)结果,直到我没有找到新的匹配项?正则表达式不适合解析任意深度树结构。根据您正在使用的regex风格,这可能是可行的,但不推荐这样做-它们很难阅读,也很难调试 我建议改为编写一个简单的解析器。您要做的是将文本分解为一组可能的标记,每个

我正在尝试匹配模板文件中的一组特定标记。然而,我希望标签是正确的 能够嵌套在自身中

我的正则表达式如下:(带/s)

小组(2)

y
x


我想要2个匹配项,而不是1个。显然,嵌套的标记集不匹配。这在正则表达式中是可能的,还是应该保留regexing group(2)结果,直到我没有找到新的匹配项?

正则表达式不适合解析任意深度树结构。根据您正在使用的regex风格,这可能是可行的,但不推荐这样做-它们很难阅读,也很难调试

我建议改为编写一个简单的解析器。您要做的是将文本分解为一组可能的标记,每个标记都可以由简单的正则表达式定义,例如:

START_TOKEN = "<!-- START [A-Za-z] -->"
END_TOKEN = ...
HTML_TEXT = ...
START_TOKEN=“”
结束标记=。。。
HTML_TEXT=。。。
迭代字符串,只要匹配这些标记,就将它们从字符串中取出,并将它们存储在单独的列表中。执行此操作时,请确保保存令牌(如果有)中的文本

然后,您可以迭代令牌列表,并根据令牌类型创建嵌套的节点树结构,每个节点包含1)原始令牌的文本,2)子节点列表


如果这看起来太复杂,您可能想看一些解析器教程。

正则表达式不适合解析任意深度树结构。根据您正在使用的regex风格,这可能是可行的,但不推荐这样做-它们很难阅读,也很难调试

我建议改为编写一个简单的解析器。您要做的是将文本分解为一组可能的标记,每个标记都可以由简单的正则表达式定义,例如:

START_TOKEN = "<!-- START [A-Za-z] -->"
END_TOKEN = ...
HTML_TEXT = ...
START_TOKEN=“”
结束标记=。。。
HTML_TEXT=。。。
迭代字符串,只要匹配这些标记,就将它们从字符串中取出,并将它们存储在单独的列表中。执行此操作时,请确保保存令牌(如果有)中的文本

然后,您可以迭代令牌列表,并根据令牌类型创建嵌套的节点树结构,每个节点包含1)原始令牌的文本,2)子节点列表


如果这看起来太复杂,您可能想看一些解析器教程。

您可以这样做:

$parts = preg_split('/(<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
$tokens = array();
$isTag = isset($tokens[0]) && preg_match('/^<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->$/', $tokens[0]);
foreach ($parts as $part) {
    if ($isTag) {
        preg_match('/^<!-- (START|END|CARET) ([a-zA-Z][a-zA-Z0-9]*) -->$/', $token, $match);
        $tokens[] = array($match[1], $match[2]);
    } else {
        if ($token !== '') $tokens[] = $token;
    }
    $isTag = !$isTag;
}
var_dump($tokens);
$parts=preg_split(“/()/”,$str,-1,preg_split_DELIM_CAPTURE);
$tokens=array();
$isTag=isset($tokens[0])&预匹配('/^$/',$tokens[0]);
foreach($parts作为$part){
如果($isTag){
预匹配(“/^$/”,$token,$match);
$tokens[]=数组($match[1],$match[2]);
}否则{
如果($token!='')$tokens[]=$token;
}
$isTag=!$isTag;
}
var_dump(代币);

这将为您提供代码的结构。

您可以这样做:

$parts = preg_split('/(<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
$tokens = array();
$isTag = isset($tokens[0]) && preg_match('/^<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->$/', $tokens[0]);
foreach ($parts as $part) {
    if ($isTag) {
        preg_match('/^<!-- (START|END|CARET) ([a-zA-Z][a-zA-Z0-9]*) -->$/', $token, $match);
        $tokens[] = array($match[1], $match[2]);
    } else {
        if ($token !== '') $tokens[] = $token;
    }
    $isTag = !$isTag;
}
var_dump($tokens);
$parts=preg_split(“/()/”,$str,-1,preg_split_DELIM_CAPTURE);
$tokens=array();
$isTag=isset($tokens[0])&预匹配('/^$/',$tokens[0]);
foreach($parts作为$part){
如果($isTag){
预匹配(“/^$/”,$token,$match);
$tokens[]=数组($match[1],$match[2]);
}否则{
如果($token!='')$tokens[]=$token;
}
$isTag=!$isTag;
}
var_dump(代币);

这将为您提供代码的结构。

很有趣。你能推荐一些语法分析教程吗?很有趣。你能推荐一些语法分析教程吗?
y 
<!-- START xList --> 
  x 
<!-- END xList --> 
<!-- CARET xList --> 
<br>
START_TOKEN = "<!-- START [A-Za-z] -->"
END_TOKEN = ...
HTML_TEXT = ...
$parts = preg_split('/(<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
$tokens = array();
$isTag = isset($tokens[0]) && preg_match('/^<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->$/', $tokens[0]);
foreach ($parts as $part) {
    if ($isTag) {
        preg_match('/^<!-- (START|END|CARET) ([a-zA-Z][a-zA-Z0-9]*) -->$/', $token, $match);
        $tokens[] = array($match[1], $match[2]);
    } else {
        if ($token !== '') $tokens[] = $token;
    }
    $isTag = !$isTag;
}
var_dump($tokens);