PHP正则表达式用[]替换嵌套()

时间:2010-07-06 00:37:54

标签: php regex

我正在尝试匹配一个字符串,请参阅示例,以便嵌套的parantheses()被[]替换,以便不破坏其他地方的解析器。在这种情况下,我想用“Arman; Dario(10040 Druento(都灵),IT)替换$ myStr”......

提前致谢!

{X:

  $myStr = "Arman; Dario (10040 Druento (Turin), IT)";
    $pattern = "/(\()([a-z,A-Z0-9_\&\/\'\-\,\;\:\.\s^\)]+)(\))/";
    if (preg_match_all($pattern,$myStr,$matches))
        {
            print_r($matches);
        }

显然,我还需要切换match_all来替换。

总结:

INPUT

$myStr = "Arman; Dario (10040 Druento (Turin), IT)";

输出

$myStr = "Arman; Dario (10040 Druento [Turin], IT)";

5 个答案:

答案 0 :(得分:4)

使用正则表达式无法可靠地执行此操作。如果您选择使用此方法,答案取决于您愿意对输入做出的假设。例如,如果您愿意假设可以替换最里面的括号,答案很简单:

preg_replace('!\(([^()]*)\)!', '{$1}', $input);

如果您专门寻找嵌套括号,请尝试:

preg_replace('!\(([^()]*)\(([^()]*)\)([^()]*)\)!', '($1{$2}$3)', $input);

答案 1 :(得分:1)

$myStr = "Arman; Dario (10040 Druento (Turin), IT)";

$pattern = "/(.*\(.*)\(([^()]+)\)(.*)/";
if (preg_match_all($pattern,$myStr,$matches))
    {
        print( $matches[1] . '[' . $matches[2] . ']' . $matches[3] );
    }

你可以通过它来运行它,直到它不匹配

while( preg_match_all($pattern,$myStr,$matches)) )
{
    $mystr = $matches[1] . '[' . $matches[2] . ']' . $matches[3];
}

答案 2 :(得分:1)

您可以使用for循环和充当堆栈的数组来执行此操作。当您找到一个打开的支架时,推入堆叠,当您发现从堆栈中弹出一个右括号时。堆栈的长度将告诉您是否应该替换当前括号。

$stack = array();
$str = "Arman; Dario (10040 Druento (Turin), IT)";
$out = "";

for ($i = 0, $l = strlen($str); $i < $l; ++$i) {
    if ($str[$i] == "(") {
        $stack[] = true;

        if (count($stack) % 2) { // alternate between ( and [
            $out .= "(";
        } else {
            $out .= "[";
        }
    } else if ($str[$i] == ")") {
        if (count($stack) % 2) {
            $out .= ")";
        } else {
            $out .= "]";
        }
        array_pop($stack);
    } else {
        $out .= $str[$i];
    }
}

以下是一些示例输入和输出:

Arman; Dario (10040 Druento (Turin), IT)
Arman; Dario (10040 Druento [Turin], IT)

a ( b ( c ( d ) ) e )
a ( b [ c ( d ) ] e )

a (b  (c) (d) (e) )
a (b  [c] [d] [e] )

a (b (c (d) (e) (f)))
a (b [c (d) (e) (f)])

这不是一个特别有效的算法(通过char构建字符串char),对于无法匹配的括号,它可能会更聪明一些,但无论如何......

答案 3 :(得分:0)

匹配嵌套括号需要解析器来实现无上下文语法。你不能用正则表达式来做。

Lime是一个用PHP编写的解析器,但似乎是放弃软件,其文档严重缺乏。

答案 4 :(得分:0)

嵌套括号不能与regular grammar匹配。因此,真正的正则表达式将无法匹配任意深度的嵌套括号。有关更详细的说明,请参阅帖子Can regular expressions be used to match nested parenthesis?

值得庆幸的是,PHP中的正则表达式实际上不是常规。 Perl“常规”表达式支持递归模式,如PHP.net所述。对于此特定问题,您是否考虑过使用str_replace()单独替换元素?如果您遇到不匹配的开括号和右括号(例如(foo (bar)),那么这只会失败。