Промучился уже очень много, поэтому созрел задать вопрос в форуме !!!
Излагаю проблему, максимально упрощённо:
Есть формула, к примеру, (x*y+cos(x))/(2*sin(x)+7*y), мне нужно одной регуляркой проверить валидность этого выражения, а тоесть проверить что каждой открытой скобе ("([{"), соответсвует её закрывающий эквивалент в томже порядке. Ограничений на вложение скобок разного вида друг в друга нет.
Мой подход первоначальный - попытался упростить задачу, ограничил количество вложений скобок до 3 уровней и попытался для каждого уровня описать регулярки. Код с регулярными выражениями получился просто громадный и скорость работы стала ощущаться (появилась ошутимая задержка).
Что в итоге я хочу получить - компактный код, который к примеру записывался бы в таком виде (\({$0}\))*, где {$0} - ссылка на часть регулярного выражения, в данном случае на всё регулярное выражение. Если рекурсию в таком виде возможно сделать в PHP, то подскажите как. Если невозможно сделать в пхп, а возможно сделать в других языках программирования (например в перл), то прошу тоже откликнуться.
Заранее ОГРОМНОЕ СПАСИБО!!!
Спустя 1 час, 34 минуты, 9 секунд (20.10.2008 - 23:28) Alchemist написал(а):
А почему это надо делать именно одной регуляркой ?
С ходу у меня получилось что-то вроде этого:
вполне возможно что это улучшаемо...
С ходу у меня получилось что-то вроде этого:
Код
if (substr_count($expr,'(') != substr_count($expr,')') ||
substr_count($expr,'{') != substr_count($expr,'}') ||
substr_count($expr,'[') != substr_count($expr,']') ||
preg_match('/\([^{]*[{}][^}]*\)|\{[^(]*[()][^)]*\}|\[[^(]*[()][^)]*\]|\[[^{]*[{}][^}]*\]|\{[^\[]*[\[\]][^\]]*\}|\([^\[]*[\[\]][^\]]*\)/',$expr)
)
echo "Invalid !!";
else
echo "OK !";
substr_count($expr,'{') != substr_count($expr,'}') ||
substr_count($expr,'[') != substr_count($expr,']') ||
preg_match('/\([^{]*[{}][^}]*\)|\{[^(]*[()][^)]*\}|\[[^(]*[()][^)]*\]|\[[^{]*[{}][^}]*\]|\{[^\[]*[\[\]][^\]]*\}|\([^\[]*[\[\]][^\]]*\)/',$expr)
)
echo "Invalid !!";
else
echo "OK !";
вполне возможно что это улучшаемо...
Спустя 2 часа, 54 минуты, 1 секунда (21.10.2008 - 02:22) rodzewich написал(а):
Цитата(Alchemist @ 20.10.2008, 20:28) [snapback]52018[/snapback]
А почему это надо делать именно одной регуляркой ?
С ходу у меня получилось что-то вроде этого:
вполне возможно что это улучшаемо...
С ходу у меня получилось что-то вроде этого:
Код
if (substr_count($expr,'(') != substr_count($expr,')') ||
substr_count($expr,'{') != substr_count($expr,'}') ||
substr_count($expr,'[') != substr_count($expr,']') ||
preg_match('/\([^{]*[{}][^}]*\)|\{[^(]*[()][^)]*\}|\[[^(]*[()][^)]*\]|\[[^{]*[{}][^}]*\]|\{[^\[]*[\[\]][^\]]*\}|\([^\[]*[\[\]][^\]]*\)/',$expr)
)
echo "Invalid !!";
else
echo "OK !";
substr_count($expr,'{') != substr_count($expr,'}') ||
substr_count($expr,'[') != substr_count($expr,']') ||
preg_match('/\([^{]*[{}][^}]*\)|\{[^(]*[()][^)]*\}|\[[^(]*[()][^)]*\]|\[[^{]*[{}][^}]*\]|\{[^\[]*[\[\]][^\]]*\}|\([^\[]*[\[\]][^\]]*\)/',$expr)
)
echo "Invalid !!";
else
echo "OK !";
вполне возможно что это улучшаемо...
Попробовал Ваше решение - работает, но притормаживает, секунд 20 думает (наверно, тестировал сложный текст) - СПАСИБО!
Объясню задачу - есть интерфейс, в котором есть возможность добавления параметров, которые в дальнейшем замыкаются друг на друга, одним из пунктов параметра - регулярка. При попадании текста в параметр уменя есть возможность опираться только на регулярки, при помощи которой текст пилится по запчастям и рассылается на другие параметры. Проблема изложенная выше - максимально упрощена, на самом деле нужно проверять нетолько скобки, но и синтаксическую валидность всего мат.выражения. Рекурсивные шаблоны - нашёл вот статейку, но рекурсия описывается только для перл, хотелосьбы получить такуюже возможность от пыха - если это вообще возможно.
Спустя 1 день, 8 часов, 26 минут, 17 секунд (22.10.2008 - 10:49) Ghost написал(а):
_____________