导语:叶子遇到一个问题,就是需要将当前菜单的子菜单在其他地方输出,叶子使用了正则表达式来实现,下面来看具体的内容。
将菜单赋给变量
我们利用wp_nav_menu中的参数echo实现将菜单赋给变量,很简单,echo参数设为false就可以了。如果你要输出变量中的菜单项,就利用php的echo命令。
$topnav=wp_nav_menu(array('container' => false,'echo' => false, 'items_wrap' => '%3$s', 'theme_location' => 'top')); echo $topnav;
找出当前菜单项的子菜单
wordPress菜单的结构是这个样子的。
<li id="menu-item-35" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-35"><a href="/">Home</a> <ul class="sub-menu"> <li id="menu-item-33" class="menu-item menu-item-type-post_type menu-item-object-tour menu-item-33"><a href="http://www.whychinadiscovery.com/tours/test11">test11</a></li> </ul> </li>
我们希望获得的值为:
<li id="menu-item-33" class="menu-item menu-item-type-post_type menu-item-object-tour menu-item-33"><a href="http://www.whychinadiscovery.com/tours/test11">test11</a></li>
下面为实现的正则表达式,我们用preg_match_all来匹配。var_dump函数是用来调试结果的,可以屏蔽。
$search = '/<li.*?class=\".*?current-menu-item.*?\".*?<ul.*?class=\".*?sub-menu.*?\".*?>(.*?)<\/ul>.*?<\/li>/is'; preg_match_all($search,$topnav,$rnav,PREG_SET_ORDER ); var_dump($rnav);
这个正则表达式可以匹配出正确的结果,但它有一个问题就是,不够严谨,有很多类似的结果都会出来。例如如果当前菜单是前面一个子菜单,它会跨li、ul匹配出后面其他菜单的sub-menu。
修改后的正则表达式
这个表达式没有使用.来代表所有的字符,而是严格按照结构,匹配应该出现的字符。
$search = '/<li[\s]*id=\"[0-9a-zA-Z\-\s]*\"[\s]*class=\"[0-9a-zA-Z\-\s_]*current-menu-item[0-9a-zA-Z\-\s_]*\"><a[\s]*href="[0-9a-zA-Z\-\s_:\/\.\x80-\xff]*">[0-9a-zA-Z\-\s_:\/\.\x80-\xff]*<\/a>[\n\r\s]*<ul[\s]*class=\"[0-9a-zA-Z\-\s_]*sub-menu[0-9a-zA-Z\-\s_]*\">(.*?)<\/ul>[\n\r\s]*<\/li>/is';
终极版正则表达
如果我们在子菜单里面有含有子菜单,那么该怎么匹配,请看终极版的匹配规则。
$search = '/<li[\s]*id=\"[0-9a-zA-Z\-\s]*\"[\s]*class=\"[0-9a-zA-Z\-\s_]*current-menu-item[0-9a-zA-Z\-\s_]*\"><a[\s]*href="[0-9a-zA-Z\-\s_:\/\.\x80-\xff]*">[0-9a-zA-Z\-\s_:\/\.\x80-\xff]*<\/a>[\n\r\s]*<ul[\s]*class=\"[0-9a-zA-Z\-\s_]*sub-menu[0-9a-zA-Z\-\s_]*\">[\n\r\s]*((<li[\s]*id=\"[0-9a-zA-Z\-\s]*\"[\s]*class=\"[0-9a-zA-Z\-\s_]*\"><a[\s]*href="[0-9a-zA-Z\-\s_:\/\.\x80-\xff]*">[0-9a-zA-Z\-\s_:\/\.\x80-\xff]*<\/a>[\n\r\s]*(<ul.*?ul>)*?[\n\r\s]*<\/li>[\n\r\s]*)+)[\n\r\s]*<\/ul>[\n\r\s]*<\/li>/is';
结束
你学会了吗?