WordPress查找当前菜单的子菜单项正则表达式

导语:叶子遇到一个问题,就是需要将当前菜单的子菜单在其他地方输出,叶子使用了正则表达式来实现,下面来看具体的内容。

将菜单赋给变量

我们利用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';

结束

你学会了吗?

发表评论

邮箱地址不会被公开。 必填项已用*标注