[英]PHP regular expression to replace nested () with []
我正在尝试匹配一个字符串,请参见示例,以便将嵌套的parantheses()替换为[],以免在其他地方破坏解析器。 在这种情况下,我想将$ myStr替换为“ Arman; Dario(10040 Druento(都灵),IT)” ...
提前致谢!
蒙特
{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)";
OUTPUT
$myStr = "Arman; Dario (10040 Druento [Turin], IT)";
使用正则表达式不能可靠地做到这一点。 如果您仍然选择使用这种方法,答案取决于您愿意对输入做出什么样的假设。 例如,如果您愿意替换最里面的括号,那么答案很简单:
preg_replace('!\(([^()]*)\)!', '{$1}', $input);
如果您正在寻找嵌套的括号,请尝试:
preg_replace('!\(([^()]*)\(([^()]*)\)([^()]*)\)!', '($1{$2}$3)', $input);
$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];
}
您可以使用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),对于不匹配的括号,它可能会更聪明,但是无论如何...
匹配嵌套括号需要解析器来实现上下文无关的语法。 您不能使用正则表达式执行此操作。
Lime是用PHP编写的解析器,但它似乎已经被抛弃,并且严重缺乏文档。
嵌套的括号不能与常规语法匹配。 因此,真正的正则表达式将无法匹配任意深度的嵌套括号。 请参阅文章可以使用正则表达式来匹配嵌套括号吗? 以获得更详细的说明。
幸运的是,PHP中的正则表达式实际上不是正则表达式。 Perl“正则”表达式支持递归模式,如PHP.net所述 。 对于此特定问题,您是否考虑过用str_replace()
分别替换元素? 仅当您遇到不匹配的开始和结束括号(例如(foo (bar)
))时,此操作才会失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.