Я пишу регулярное выражение для PHP preg_match_all
найти все ifs(...)
со всем его содержимым из строки. (В моем примере у меня есть только один ifs, так как он не является корнем проблемы.)
Вот что у меня так далеко:
Шаблон: /ifs\(.*?\)/i
Строка: =iferror(ifs(OR("foo", "bar"),"a",OR("tar", "scar"),"b",OR("lar"),"d"),"c")
Токовый выход: ifs(OR("foo", "bar")
Ожидаемый результат: ifs(OR("foo", "bar"),"a",OR("tar", "scar"),"b",OR("lar"),"d")
Проблема: регулярное выражение находит первые закрывающие скобки.
Куда я иду не так? А как бы вы взялись за вложенные скобки?
Демо-версия: https://regex101.com/r/SgBqbW/1
На самом деле вы можете сделать это благодаря возможности PHP рекурсивные регулярные выражения. Это вдохновлено этот комментарий на этой странице:
$string = '=iferror(ifs(OR("foo", "bar"),"a",OR("tar", OR("scar", "baa")),"b",OR("lar"),"d"),"c")
blah blah ifs(OR("foo", "bar"),"a") and another one ifs("a", OR("tar", OR("scar", "baa")),"b",OR("lar"),"d")';
$regex = '/ifs(\(((?>[^()]+)|(?-2))*\))/';
preg_match_all($regex, $string, $matches);
print_r($matches[0]);
Выход:
Array (
[0] => ifs(OR("foo", "bar"),"a",OR("tar", OR("scar", "baa")),"b",OR("lar"),"d")
[1] => ifs(OR("foo", "bar"),"a")
[2] => ifs("a", OR("tar", OR("scar", "baa")),"b",OR("lar"),"d")
)
Других решений пока нет …