这个正则我在正则表达式测试器里测试通过,但拿到PHP中就不可以使用~求解这个如何写才能在PHP中实现?
$patterns = '/'.$begintag.'([\s\S]*?)(((?<Open>'.$begintag.')([\s\S]*?))+((?<-Open>'.$endtag.')([\s\S]*?))+)*(?(Open)(?!))'.$endtag.'/';
以上是PHP的语句,下面是$begintag和$endtag变量被赋值后的正则规则示例:
\{Cms:cates(\s([^\}]*)|)\}([\s\S]*?)(((?<Open>\{Cms:cates(\s([^\}]*)|)\})([\s\S]*?))+((?<-Open>\{\/Cms:cates(\s*?)\})([\s\S]*?))+)*(?(Open)(?!))\{\/Cms:cates(\s*?)\}难道PHP不支持正则平衡组,正则堆栈的用法吗?
PHP正则表达式平衡组堆栈多层嵌套
$patterns = '/'.$begintag.'([\s\S]*?)(((?<Open>'.$begintag.')([\s\S]*?))+((?<-Open>'.$endtag.')([\s\S]*?))+)*(?(Open)(?!))'.$endtag.'/';
以上是PHP的语句,下面是$begintag和$endtag变量被赋值后的正则规则示例:
\{Cms:cates(\s([^\}]*)|)\}([\s\S]*?)(((?<Open>\{Cms:cates(\s([^\}]*)|)\})([\s\S]*?))+((?<-Open>\{\/Cms:cates(\s*?)\})([\s\S]*?))+)*(?(Open)(?!))\{\/Cms:cates(\s*?)\}难道PHP不支持正则平衡组,正则堆栈的用法吗?
PHP正则表达式平衡组堆栈多层嵌套
$s =<<< TXT
其他文本其他文本 <div>仅单层 </div> </div>(注意:后面多一个 </div>)
其他文本其他文本其他文本
<div>外层
<div>中层
<div>内层 </div>
</div>
</div>
# 这是另一种情况
# start 闭合错误
<div>外层
<div>中层
<div>内层 </div>
</div>
</font>
# end 闭合错误
其他文本 <font>外层 <span>里层 </span> </font>其他文本其他文本……
TXT;
$p = "/<([a-z]+)[^>]*>([^<>]|(?R))*<\/\\1>/is";preg_match_all($p,$s,$m);print_r($m[0]);Array
(
[0] => <div>仅单层 </div>
[1] => <div>外层
<div>中层
<div>内层 </div>
</div>
</div>
[2] => <div>中层
<div>内层 </div>
</div>
[3] => <font>外层 <span>里层 </span> </font>
)
比如我要用Cms:navlist来匹配下面一段,按你发的规则改过,然后就不好用:
<ul>
{Cms:navlist }
<dl class="fl {if condition='$navlist.id eq 1'}on{elseif condition='$navlist.id eq 4' /}light{/if}">
<dt><a href="{$navlist.url}">{$navlist.title}</a></dt>
{Cms:navlist pid="$navlist['id']" item="navlist1" key='key1' elem='dd'}
<div><a href="{$navlist1.url}">{$navlist1.title}</a></div>
{/Cms:navlist}
</dl>
{/Cms:navlist}
</ul>
$str =<<<'EOF'
<ul>
{Cms:navlist }
<dl class="fl {if condition='$navlist.id eq 1'}on{elseif condition='$navlist.id eq 4' /}light{/if}">
<dt><a href="{$navlist.url}">{$navlist.title}</a></dt>
{Cms:navlist pid="$navlist['id']" item="navlist1" key='key1' elem='dd'}
<div><a href="{$navlist1.url}">{$navlist1.title}</a></div>
{/Cms:navlist}
</dl>
{/Cms:navlist}
</ul>
EOF;preg_match('#\{(Cms:[a-z]+)[^\}]*\}(([^\{\}]|{(?!=Cms)[^\}]*\}|(?R))*)\{\/\\1\}#i',$str,$val);
print_r($val);
就是这个,就是这个,不过有点点问题:我这个用于解析模板标签,在{Cms:navlist}{/Cms:navlist}里面有可能嵌套其他{Cms:xxx}{/Cms:xxx}类型的标签,也有可能是{if}{/if}或者{foreach}{/foreach}或者变量{$aaa.bbb}或者其他以{}包裹起来的东西,但只要不是{Cms:navlist}就可以……
这样的话是不是上面语句的(?!=Cms)要改成(?!=Cms:navlist)?
就是这个,就是这个,不过有点点问题:我这个用于解析模板标签,在{Cms:navlist}{/Cms:navlist}里面有可能嵌套其他{Cms:xxx}{/Cms:xxx}类型的标签,也有可能是{if}{/if}或者{foreach}{/foreach}或者变量{$aaa.bbb}或者其他以{}包裹起来的东西,但只要不是{Cms:navlist}就可以……
这样的话是不是上面语句的(?!=Cms)要改成(?!=Cms:navlist)?
我对(?!=)这个语法一只不是很明白
<ul>
{Cms:navlist }
<dl class="fl {if condition='$navlist.id eq 1'}on{elseif condition='$navlist.id eq 4' /}light{/if}">
<dt><a href="{$navlist.url}">{$navlist.title}</a></dt>
{Cms:navlist pid="$navlist['id']" item="navlist1" key='key1' elem='dd'}
<div><a href="{$navlist1.url}">{$navlist1.title}</a></div>
{/Cms:navlist}
</dl>{/Cms:navlist}
{/Cms:navlist}<!--这里多一组关闭标签-->
</ul>PHP真的就没有正则堆栈的支持吗?我感觉这种递归的正则还是有很大的缺陷的
版主大大说的太对了,正则也不是万能,正则主要是处理模式化的东西,而如果非模式化的东西最好还是有代码来完成,否则就太费力了。
例如你说的那个情况,完全可以多用几次查找就可以实现,例如真正用代码实现一个堆栈的方式来处理。
话是这样说不错~但我实在是不明白为什么PHP正则为什么不支持其他语言正则的组平衡语法~
是可以用代码来完成,但我觉得PHP是一个解释性语言,用另外的语句来实现远不如直接用内置的函数来做性能高。如果是C代码那种编译型的语言,需要的功能不多的情况下倒是完全没必要引用外部扩展库,自己写几行代码性能上应该会更高一些~
如果用PHP代码来另外完成这个标签查找匹配的操作,会另外多执行好多好多次循环、正则等操作,纠结中~
是要逐层剥离,但现在层次的判断有些问题,只有层次判断OK以后才能继续下一步的逐层分析替换内容~我估计PHP的正则也许真的实现不了了,看来只能损失性能来写专门的语法分析代码了~
是要逐层剥离,但现在层次的判断有些问题,只有层次判断OK以后才能继续下一步的逐层分析替换内容~我估计PHP的正则也许真的实现不了了,看来只能损失性能来写专门的语法分析代码了~
我也是多次遇到这个问题了,一个是想写cms,另外一个是html标签选择器,不过都没能实现。