1

我需要根据在它的父简码中设置的活动号码动态地将一个活动类添加到 wordpress 中的简码。

父母看起来像这样:

$active = 3;
$output .= "\n\t\t".wpb_js_remove_wpautop($content);

$content 变量在技术上可以包含短代码标签之间的任何内容,但具体来说,应该包含更多的子短代码(它是一个标签短代码,因此父标签是标签,子标签是标签)。

我需要做的是解析并替换$content第 N 个($active变量)实例[vc_tab[vc_tab active="true"

我意识到有更好的方法来设计短代码来弥补这一点,但我能做的有限,因为我正在修改 Visual Composer 以使用 Bootstrap 选项卡而不是 jQuery 和 Bootstrap 选项卡需要两个元素上的活动类<li>,但是<div class="tab-pane">我不希望用户必须向父简码添加一个活动号码,并为孩子添加一个活动的真/假,因为这会让人感到困惑。

到目前为止,从谷歌搜索我只能找到替换第一次出现或所有出现,而不是第 N 个。

暂时我正在使用 jQuery 来使适当的<div>活动,但它会导致不受欢迎的 FOUC,其中在加载时没有可见的窗格,然后在 jQuery 运行时弹出到位。

$('.tabs-wrap').each(function(){
  var activeTab = $(this).find('.tabbed li.active a').attr('href');
  $(this).find(activeTab).addClass('active');
});  
4

2 回答 2

3

我不熟悉你提到的工具,所以我不能说是否有更好的方法来实现最终目标,但你可以使用以下方法替换第 N 次出现的东西preg_replace_callback

$active = 3;     // target occurrence
$occurrence = 0; // counter
$output = preg_replace_callback(
    '/\[vc_tab/',
    function ($matches) use(&$occurrence, $active) {
        return ++$occurrence != $active
            ? $matches[0]
            : '[vc_tab active="true"';
    },
    $output,
    $active
);

看到它在行动

除非出现计数器等于目标数,否则这通过用其自身替换每个出现来工作。

请注意,$active为了获得免费的性能提升,我已经通过了替换的最大出现次数;这将导致在替换事件后preg_replace_callback停止$active(我们知道之后的所有事件都将被它们自己替换,所以继续下去没有意义)。

于 2013-08-15T20:25:11.203 回答
3

这是一个有趣的问题,让我思考是否真的需要一个正则表达式来做到这一点。

我的结论是,我不相信你这样做。您需要做的就是找到 的出现Nth $needle,并将其替换为您的替换。这可以通过一些简单的字符串操作来实现,如下所示:

  1. 定义一些变量。您的输入字符串、您的$active索引、$needle我们正在查找的字符串以及$replace我们将替换Nth匹配项的内容。

    $string  = "[vc_tab [vc_tab [vc_tab [vc_tab [vc_tab [vc_tab";
    $active  = 3;
    $needle  = "[vc_tab";
    $replace = '[vc_tab active="true"';
    
  2. 现在,我们需要确保$needles 中有足够的 s $string,否则我们无法进行这种替换。

    if( substr_count( $string, $needle) < $active) {
        throw new Exception("There aren't enough needles in the string to do this replacement");
    }
    
  3. 现在,我们知道我们可以进行替换。所以让我们$index在字符串中Nth找到$needle结束的地方:

    $count = 0; $index = 0;
    while( $count++ < $active) {
        $index = strpos( $string, $needle, $index) + strlen( $needle);
    }
    
  4. 现在,$index在字符串中指向这里:

    [vc_tab [vc_tab [vc_tab [vc_tab [vc_tab [vc_tab
                           ^
                           Here
    

    我们现在可以做一些简单substr()的 's 来形成最终的字符串:

    $result = substr( $string, 0, $index - strlen( $needle)) . $replace . substr( $string, $index);
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^              ^^^^^^^^^^^^^^^^^^^^^^^^
              Before the Nth match                                        After the Nth match
    

    所以,我们最终连接:

    • [vc_tab [vc_tab
    • [vc_tab active="true"
    • [vc_tab [vc_tab [vc_tab

这导致我们的最终输出

[vc_tab [vc_tab [vc_tab active="true" [vc_tab [vc_tab [vc_tab

在演示中试一试!

于 2013-08-15T21:01:56.310 回答