Здравствуйте уважаемые. Пишу серьезный проект и понадобилось сделать небольшой модуль понимающий урезанный SQL для легкой замены баз данных.
Требуется разобрать команду:
SELECT `name` FROM table WHERE name = 1
Вы понимаете, что name может быть и без кавычек, а 1 может быть как в одинарных, так и в двойных кавычках, а также могут использоваться экранированные кавычки. Т.к. версия облегченная, то OR и т.п. использоваться не будет. Сделал разбор строки нижеуказанным кодом. Хотелось бы спросить у других, кто что думает. Можно ли облегчить алгоритм? Может кто знает другой алгоритм? Может как-то можно сэкономить ресурсы при выполнении?
$command = "SELECT `name` FROM table WHERE name = 1 ";
# разобрал с помощью регулярок. В $temp3 попало все после WHERE
my$length = length($temp3);
my($i,$flag,$pos_beg,$pos_end,$pos_beg_val,$pos_end_val);
my$step = 0;
my@temp3 = split(/|/, $temp3);
for ($i = 0; $i < ($length+1); $i++)
{
if ($step == 0)
{
if ($temp3[$i] ne " ")
{
if ($temp3[$i] eq "`")
{
$flag = "`";
$pos_beg = $i;
$step = 1;
next;
}
else
{
$flag = " ";
$pos_beg = $i-1;
$step = 1;
next;
}
}
}
if ($step == 1)
{
if ($flag eq "`")
{
if ($temp3[$i] eq "`" && $temp3[$i-1] ne "\\\\")
{
$pos_end = $i;
$step = 2;
next;
}
}
elsif ($flag eq " ")
{
if ($temp3[$i] eq " " || $temp3[$i] eq "=")
{
$pos_end = $i;
$step = 2;
next;
}
}
}
if ($step == 2) {if ($temp3[$i-1] eq "=") {$step = 3;}}
if ($step == 3)
{
if ($temp3[$i] ne " ")
{
if ($temp3[$i] eq "\'")
{
$flag = "\'";
$pos_beg_val = $i;
$step = 4;
next;
}
elsif ($temp3[$i] eq "\\"")
{
$flag = "\\"";
$pos_beg_val = $i;
$step = 4;
next;
}
else
{
$flag = " ";
$pos_beg_val = $i - 1;
$step = 4;
next;
}
}
}
if ($step == 4)
{
if ($flag eq "\'")
{
if ($temp3[$i] eq "\'" && $temp3[$i-1] ne "\\\\")
{
$pos_end_val = $i;
last;
}
}
if ($flag eq "\\"")
{
if ($temp3[$i] eq "\\"" && $temp3[$i-1] ne "\\\\")
{
$pos_end_val = $i;
last;
}
}
elsif ($flag eq " ")
{
if ($temp3[$i] eq " " || $temp3[$i+1] eq "")
{
$pos_end_val = $i;
last;
}
}
}
}
my$temp4 = substr($temp3, $pos_beg_val+1, ($pos_end_val - ($pos_beg_val+1)));
$temp3 = substr($temp3, $pos_beg+1, ($pos_end - ($pos_beg+1)));
# в $temp3 у нас название аргумента, в $temp4 значение аргумента.