Регулярное выражение для пользовательского поиска (PHP)

12 3
Sanu0074
На сайте с 31.08.2012
Offline
110
1149

Сделал поиск в админке, добавил возможность пользователю искать совпадения в конкретных колонках таблицы с контентом, например он жмет на нужные кнопки и javascripto'm в строке поиска формируется подобное:

:name=первая && (:id>40 && :sect=content)

Рашифровка:

:name - это имя поля в таблице

&& и || - эквивалент AND и OR

скобки самособой понятно....

В итоге когда эта строка попадает на сервер, скрипт должен ее разбить и превратить в следующее,

будет строка такого вида:

name LIKE ? && (id> && sect LIKE ?)

И массив такого вида:

array('первая',40,'content')

Как это сделать? я голову ломаю, не могу составить регулярку кот все сделает. Тут следует понять, что данные могут меняться, скобок может не быть или быть несколько, знаки использую только >,<,= покачто других не придумал, знак "=" заменяем на "LIKE ?". Помогите решить задачку пожалуйста? И хочу видеть ваши замечания, насколько это тупо..) p.s. но хочу сделать именно так)

Mad_Man
На сайте с 10.11.2008
Offline
162
#1

Вы пытаетесь изобрести лексер. Их и юзайте.

Sanu0074
На сайте с 31.08.2012
Offline
110
#2

Mad_Man, Первый раз о них слышу. Мне нужна строка такого вида: "name LIKE ? && (id> && sect LIKE ?)" - потому что я использую обёртку для PDO, которая из такой строки + массив делает запрос. Не знаю как прикрутить лексемы(

siv1987
На сайте с 02.04.2009
Offline
427
#3


$str = ':name=первая && (:id>40 && :sect=content)';
$param = array();

preg_match_all('/:([\w_]+)\s*([<>=]{1,2})\s*(["\'].*?["\']|[^\s()]+)/', $str, $out);
for($i=0; $i<count($out[0]); $i++){
$key = $out[1][$i];
$sign = $out[2][$i];
$val = $out[3][$i];

$str = str_replace($out[0][$i], $key.(($sign == '=') ? ' LIKE' : $sign).' ?', $str);
$param[] = $val;
}

echo $str;
print_r($param);

Грубый такой вариант. Если вам нужно разобрать полностью выражение пишите свой парсер с блэкджеком и девушками.

Sanu0074
На сайте с 31.08.2012
Offline
110
#4

siv1987,siv1987, спасибо, протестил ваш вариантик, немного не так в результирующей строке:

name LIKE ? && (:id>40 && sect LIKE ?) - здесь вместо ":id>40" - должно быть просто "id>" и в массиве $param всего два элемента, а должно быть три и вторым должен быть параметр "40".

---------- Добавлено 08.01.2015 в 21:34 ----------

Пробовал такую строку исходную - :name=первая && :sect=abc - работает

но если в строке уже есть знак > и число то все работает не так

Например при такой исходной строке :name=первая && :sect>40 - результирующая выглядит так - name LIKE ? && :sect>40 и массив так:

array(1) {
[0]=>
string(12) "первая"
}
т.е. такой же косячок что и с первоначальным вариантом.
siv1987
На сайте с 02.04.2009
Offline
427
#5

Конкретно на коде выше я смотрел и подобных проблем небыло. Да и по идее регулярка должна отработать как нужно. Проверяйте свой код.

Sanu0074
На сайте с 31.08.2012
Offline
110
#6

siv1987, я запускал код, если попадается знак ">" - то отрабатывает не верно. Я выше описал результат тестирования - какую строку кормил и что на выдаче получил

siv1987
На сайте с 02.04.2009
Offline
427
#7

Хз. Попробуйте чтоли экранировать эти символы в регулярным выражении.

Sanu0074
На сайте с 31.08.2012
Offline
110
#8

siv1987, всеравно результат тот же(

---------- Добавлено 08.01.2015 в 23:19 ----------

вся соль в знаках > и <

не могу понять почему

siv1987
На сайте с 02.04.2009
Offline
427
#9
Sanu0074
На сайте с 31.08.2012
Offline
110
#10

siv1987, и правда все работает, извеняюсь, но почемуж в моем скрипте непашет как надо( ведь все тоже на входе

12 3

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий