搜索

首页  >  问答  >  正文

求教一个PHP正则表达式的问题

求教一个PHP正则表达式的问题。 一个字符串形如 abcdeXeeeY((XabcYcddX))Xmmdkf((adjjkYxxx)), 现在想把包含在(( ))的内的X和Y分别替换成 $ 和 @, 用preg函数如何做到呢?

PHP中文网PHP中文网2774 天前508

全部回复(2)我来回复

  • 怪我咯

    怪我咯2017-04-10 14:36:18

    我不是正则表达式的骨灰级大神,我相信很多人也不是。

    所以我建议,把事情做的简单显然一些,减少很tricky的技巧未尝不是一件好事:

    $patt = '/\(\([^\(\)]*?\)\)/';
    $subj = 'abcdeXeeeY((XabcYcddX))Xmmdkf((adjjkYxxx))';
    echo preg_replace_callback($patt, function ($matches) { 
            return str_replace('Y', '@', str_replace('X', '$', $matches[0]));
        }, $subj);
    // abcdeXeeeY(($abc@cdd$))Xmmdkf((adjjk@xxx))
    

    注1:匿名函数语法,需要 php 5.3+ 的支持。低版本php需要将回调函数按一般函数定义。
    注2:这个答案并没有考虑双括号组嵌套的情况。

    回复
    0
  • 黄舟

    黄舟2017-04-10 14:36:18

    深入学习一下正则也无妨,下面是我的解决方案, 只替换了X,看明白后把Y加进去不难。

    $s = 'abcdeXeeeY((XabXYXddX))Xmmdkf((adjjkYxxx))';
    $count = 1;
    
    while (0 < $count) {
        $s = preg_replace(
            array(
                '/(?<=\(\()([^\(\)X]*?)X/',
                '/X([^\(\)X]*?)(?=\)\))/',
            ),
            array(
                '\1$',
                '$\1',
            ),
            $s,
            -1,
            $count
        );
    
        var_dump($s);
    }
    
    /*
    string(42) "abcdeXeeeY(($abXYXdd$))Xmmdkf((adjjkYxxx))"
    string(42) "abcdeXeeeY(($ab$Y$dd$))Xmmdkf((adjjkYxxx))"
    string(42) "abcdeXeeeY(($ab$Y$dd$))Xmmdkf((adjjkYxxx))"
     */
    

    说明:主要是用了正则里面的 零宽断言 , 但 preg_replace 无法重用已经匹配过的内容,所以加了个循环控制。

    应该还有更优的方案,我这算是抛砖引玉吧。

    回复
    0
  • 取消回复