【问题标题】:How to replace everything between {} [] () braces from a string?如何替换字符串中 {} [] () 大括号之间的所有内容?
【发布时间】:2013-11-25 18:02:54
【问题描述】:

我想删除大括号内的所有内容。例如,如果字符串是:

[hi] helloz [hello] (hi) {jhihi}

那么,我希望输出仅为helloz

我正在使用下面的代码,但是在我看来应该有更好的方法,是吗?

$name = "[hi] helloz [hello] (hi) {jhihi}";
$new  =  preg_replace("/\([^)]+\)/","",$name); 
$new = preg_replace('/\[.*\]/', '', $new);  
$new = preg_replace('/\{.*\}/', '', $new);  
echo $new;

【问题讨论】:

    标签: php regex string replace preg-replace


    【解决方案1】:

    这应该可行:

    $name = "[hi] helloz [hello] (hi) {jhihi}";
    echo preg_replace('/[\[{\(].*?[\]}\)]/' , '', $name);
    

    将其粘贴到以下位置:http://writecodeonline.com/php/ 以查看它的工作原理。

    【讨论】:

    • 如果您在其中一个大括号内有另一个右大括号,您将遇到问题 $name = "[h)i] helloz [hello] (hi) {jhihi}";
    • 是的,但这不是选项之一,所以我没有考虑到它。没有必要让事情变得更难。
    • @DamienOvereem 不用担心(我同意),我只是提醒 OP 以后不要遇到问题。
    【解决方案2】:

    [旧答案]

    如果需要,可以处理嵌套括号和方括号或大括号的模式:

    $pattern = '~(?:(\()|(\[)|(\{))(?(1)(?>[^()]++|(?R))*\))(?(2)(?>[^][]++|(?R))*\])(?(3)(?>[^{}]++|(?R))*\})~';
    
    $result = preg_replace($pattern, '', $str);
    

    [编辑]

    只删除平衡良好的部分并考虑三种括号的模式:

    $pattern = '~
        \[ [^][}{)(]*+ (?: (?R) [^][}{)(]* )*+  ]
      |
        \( [^][}{)(]*+ (?: (?R) [^][}{)(]* )*+ \)
      |
        {  [^][}{)(]*+ (?: (?R) [^][}{)(]* )*+  }
    ~xS';
    

    这种模式效果很好,但是当目标只是删除字符串中的括号部分时,额外的类型检查有点过头了。但是它可以用作子模式来检查字符串中所有类型的括号是否平衡。


    一种只删除平衡部分的模式,但这次只考虑最外面的括号类型,忽略内部的其他类型的括号(与旧答案的行为相同,但更有效且没有无用的条件测试)

    $pattern = '~
        \[ ( [^][]*+ (?: \[ (?1) ] [^][]* )*+ )  ]
      |
        \( ( [^)(]*+ (?: \( (?2) ] [^)(]* )*+ ) \)
      |
         { ( [^}{]*+ (?:  { (?3) } [^}{]* )*+ )  }
    ~xS';
    

    【讨论】:

    • 编译失败:递归调用可能在第 4 行的偏移 34 处无限循环
    • @ThiagoPires:谢谢,但实际上这种模式很复杂,可以以更有效的方式做同样的事情。我会编辑这个答案。
    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多