我正在尝试匹配一个字符串,请参阅示例,以便嵌套的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)";
答案 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)
),那么这只会失败。