请求修改PHP函数以支持嵌套IF转合法三元表达式
重构transformIfStatements函数以支持多层嵌套IF公式
需要重构transformIfStatements函数,使其能有效处理嵌套IF公式,当前函数在嵌套层级超过一层时无法正常工作。
原函数代码
public function transformIfStatements(string $formulaText): string { $formulaText = preg_replace_callback( '/IF\(\s*([^,]+)\s*,\s*(IF\([^)]+\)|[^,]+)\s*,\s*(IF\([^)]+\)|[^)]+)\s*\)/', function ($matches) { return '(' . trim($matches[1]) . ') ? (' . trim($matches[2]) . ') : (' . trim($matches[3]) . ')'; }, $formulaText ); return $formulaText; }
测试用例
用例1:单层IF
- 输入:
"IF(1>10, "Large", "Medium")" - 输出:
"(1>10) ? ("Large") : ("Medium")"// 有效
用例2:两层嵌套IF
- 输入:
"IF(1>10, IF(44>20, "Large", "Medium"), "Small")" - 输出:
"(1>10) ? ((44>20) ? ("Large") : ("Medium")) : ("Small")"// 有效
用例3:三层嵌套IF(原函数处理失效)
- 输入:
"IF(1>10, IF(44>20, "Large", IF(4<5, "Tiny", "Medium")), "Small")" - 原函数输出:
"(1>10) ? ((44>20) : ("Large") ? ((4<5) : ("Tiny") ? ("Medium"))) : ("Small")"// 无效 - 期望输出:
"(1>10) ? ((44>20) ? ("Large") : ((4<5) ? ("Tiny") : ("Medium"))) : ("Small")"
说明:实际场景中输入可能为
"IF(A1>10, IF(A1>20, "Large", IF(A1<5, "Tiny", "Medium")), "Small")",上述用例为简化示例。
解决方案
原函数的问题在于单次正则替换无法处理深层嵌套,且正则表达式无法正确识别嵌套括号的边界。通过循环替换最内层IF结构的方式,可以逐层处理所有嵌套层级:
public function transformIfStatements(string $formulaText): string { do { $original = $formulaText; // 匹配最内层IF:分支内容中不再包含IF(...)结构 $formulaText = preg_replace_callback( '/IF\(\s*([^,]+?)\s*,\s*((?!IF\().+?)\s*,\s*((?!IF\().+?)\s*\)/', function ($matches) { return '(' . trim($matches[1]) . ') ? (' . trim($matches[2]) . ') : (' . trim($matches[3]) . ')'; }, $formulaText ); } while ($formulaText !== $original); return $formulaText; }
方案说明
- 循环替换:每次替换后检查内容是否变化,直到没有可替换的IF结构,确保所有嵌套层级都被处理。
- 匹配最内层IF:正则表达式使用
(?!IF\().+?确保只匹配不包含IF语句的分支内容,每次优先转换最内层的IF,转换后外层的嵌套IF会成为新的可匹配对象。
此方案可支持任意层级的嵌套IF转换,同时兼容原有单层、两层嵌套的处理逻辑。
内容的提问来源于stack exchange,提问作者David_
相关产品推荐
相关产品推荐

