Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проверка формата строки 
V
    Опции темы
bars80080
Дата 24.11.2009, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



значит, есть у нас строка

$str = '(A and B) or C';

эта строка пойдёт в запрос:
Код

$sql = 'SELECT * FROM `table_name` WHERE '.$str;
но предварительно перед подстановкой в ней A, B, C, D и т.д. будут заменены на соответствующие выражения
A => `field1`=2
B => `field2`>5
и так далее

соответственно, надо вначале проверить формат строки, чтобы не было лишних символов, типа (A and + B) 111 or C
чтобы все скобки открывали/закрывались
и что самое важное - выполнялось логическое построение, т.е. не образовывалось хвостов в воздухе (A and ) or C

третий пункт, как я понимаю без поллитра не разберёшь. слишком уж интеллектуальный механизм получается надо сделать. хотя раз mysql он реализован, значит сделать было бы можно

но вот разобраться хотя бы с первыми двумя:
1. чтобы не было лишних символов, типа (A and + B) 111 or C /должны остаться A, B, ... Z, and, or, (, )/
2. чтобы все скобки открывали/закрывались

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

вот. помогите, кто чем может


п.с. в принципе, мне не шибко важно, если бы строка имела вид не (A and B) or C, а (0 and 1) or 2
просто с буковками вменяемей смотрится

PM MAIL WWW   Вверх
patap
Дата 24.11.2009, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 893
Регистрация: 7.5.2005
Где: Украина, Зп

Репутация: 26
Всего: 40



нужно любой вариант учесть? 
к примеру

Код
(A and B) or ((D and C) or (E and F))



--------------------
На боку кобура болталась, сзади шашка отцовская звякала. 
Впереди меня все хохотало, а позади все плакало (с)
PM MAIL ICQ   Вверх
bars80080
Дата 24.11.2009, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



Цитата(patap @  24.11.2009,  16:34 Найти цитируемый пост)
нужно любой вариант учесть? 

да, любой вариант. в том числе и этот
PM MAIL WWW   Вверх
NLspieler
Дата 24.11.2009, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 619
Регистрация: 13.10.2008
Где: Берлин

Репутация: 16
Всего: 19



А такой формат допустим?
A and B and C
?


Если нет, то третья проблема, да и вся задача решается без особых проблем! 

Нужна некая функция, которая будет рекурсивно проверять каждую скобку.
Примерная структура, если писать словами, будет такой


Функция test ($text)
{
    Ругулярка  
    [A-Z] [or|and] [A-Z]
    Если подходит, то возвратить true


    Если не подходит, то проверить
    \((.+)\) [or|and] \((.+)\)
    Если совпадает, то 
    return test (первая скобка) and test (содержимое второй скобки)

    Иначе, если не совпадает, то проверить 
    \((.+)\) [or|and] [A-Z]
    return test (Содержимое скобки)
    
    Иначе, если и это не совпадает, то проверить
    [A-Z] [or|and] \((.+)\)
    return test (Содержимое скобки)    
    
    Иначе
    retuen false
}

Если не понятно, попробую написать


PM MAIL   Вверх
bars80080
Дата 24.11.2009, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



Цитата(NLspieler @  24.11.2009,  17:12 Найти цитируемый пост)
A and B and C

и такой тоже


Цитата(NLspieler @  24.11.2009,  17:12 Найти цитируемый пост)
Ругулярка  
    [A-Z] [or|and] [A-Z]
    Если подходит, то возвратить true

я уже здесь споткнусь. как отсеять из (AB and C) вот это сочетание - AB?

да, в этом конкретном случае, по сути исправлять наверное особо то ничего и не требуется. достаточно установить, что неправильный формат и выдать false. пущай сам ручками исправляет



кстати, кодировка - utf8

Цитата(NLspieler @  24.11.2009,  17:12 Найти цитируемый пост)
Если не понятно

 smile 
PM MAIL WWW   Вверх
Pitlord
Дата 24.11.2009, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 246
Регистрация: 31.10.2009

Репутация: 4
Всего: 7



Причём тут A, B, ...? Составляйте сразу выражение "(field1 > 5 and field2 = 6) or 1=2" и проверяйте с помощью конечных автоматов (регулярками тут разве что на token'ы разбивать, не более).

Вообще это дикая идея позволить пользователю составлять своё условие?

Это сообщение отредактировал(а) Pitlord - 24.11.2009, 19:00
PM MAIL   Вверх
NLspieler
Дата 24.11.2009, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 619
Регистрация: 13.10.2008
Где: Берлин

Репутация: 16
Всего: 19



Ура!!! Заработало!!!
Правда пока только упрощенная версия, которая не позволяет написать A and B and C
Приходится писать A and (B and C),
сейчас еще подумаю, может сварганю полную версию.
Код

<?
$str = '(A and B) and (A or (C and D))' ;

if  ( test ($str) ) echo 'alles OK';
else echo 'nicht alles OK' ;



function test ($text)
{
    if (  preg_match ('/^[A-Z] (or|and) [A-Z]$/' , $text , $matches) )
    {
        return TRUE ;
    }
    elseif ( preg_match ('/^\((.+)\) (or|and) \((.+)\)$/' , $text , $matches) )
    {
        return test ($matches[1]) and test ($matches[3]) ;
    }
    elseif ( preg_match ('/^\((.+)\) (or|and) [A-Z]$/' , $text , $matches) )
    {
        return test ($matches[1]) ;
    }
    elseif ( preg_match ('/^[A-Z] (or|and) \((.+)\)$/' , $text , $matches) )
    {
        return test ($matches[2]) ;
    }   
    else return FALSE ;
}

?>


Добавлено через 13 минут и 6 секунд
Версия номер 2, позволяет писать любое количество пробелов, там где это допустимо синтаксисом.

Код

<?
$str = '(   A    and    C   )  and (A or (C and D))  ' ;

if  ( test ($str) ) echo 'alles OK';
else echo 'nicht alles OK' ;



function test ($text)
{
    if (  preg_match ('/^\s*[A-Z]\s+(or|and)\s+[A-Z]\s*$/' , $text , $matches) )
    {
        return TRUE ;
    }
    elseif ( preg_match ('/^\s*\((.+)\)\s+(or|and)\s+\((.+)\)\s*$/' , $text , $matches) )
    {
        return test ($matches[1]) and test ($matches[3]) ;
    }
    elseif ( preg_match ('/^\s*\((.+)\)\s+(or|and)\s+[A-Z]\s*$/' , $text , $matches) )
    {
        return test ($matches[1]) ;
    }
    elseif ( preg_match ('/^\s*[A-Z]\s+(or|and)\s+\((.+)\)\s*$/' , $text , $matches) )
    {
        return test ($matches[2]) ;
    }   
    else return FALSE ;
}

?>

PM MAIL   Вверх
bars80080
Дата 24.11.2009, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



Цитата(Pitlord @  24.11.2009,  17:59 Найти цитируемый пост)
Составляйте сразу выражение "(field1 > 5 and field2 = 6) or 1=2"

не знаю. по-моему проще проверить пока строка не заполнилась апострофами, неизвестными именами полей, знаками = > < , да ещё и служебными словами LIKE, REGEXP и прочее


Цитата(Pitlord @  24.11.2009,  17:59 Найти цитируемый пост)
 и проверяйте с помощью конечных автоматов

что есть конечный автомат?



NLspieler, спасибо за труды, попробую завтра потестить

Добавлено через 2 минуты и 49 секунд
Цитата(Pitlord @  24.11.2009,  17:59 Найти цитируемый пост)
Вообще это дикая идея позволить пользователю составлять своё условие?

есть такие пользователи

в крайнем случае для штурманского (административного) аппарата сгодится
PM MAIL WWW   Вверх
NLspieler
Дата 25.11.2009, 02:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 619
Регистрация: 13.10.2008
Где: Берлин

Репутация: 16
Всего: 19



Сам не могу в это поверить, но у меня получилась полная версия, которая полностью выполняет поставленную задачу!

Смысл в том, что функция находит скобки, в которых больше нет скобок.
Проверяет, при помощи вспомогательной функции, все ли там в порядке. 
Проверить Z and Z and Z and Z ... на правильность не составляет особого труда.

Если все ок, то заменяет эти найденные скобки на букву Z и пропускает результат еще раз через эту же функцию.
Это длится до тех пор, пока не будет обнаружена ошибка или пока скобок уже не останется. 
В этом случаи происходит последний запуск вспомогательной функции и возвращается ее результат.

Скорость обработки представленного мною примера занимает менее половины милисекунды.

Код

<?
$str = '(A and (G and I) or    H    or B) 
and (B or (C and (D or E or G)))' ;

if (test ($str)) echo 'alles OK' ;
else echo 'nicht alles OK' ;




function test ($text , $replace = FALSE)
{
    if (!$replace)
    {
        $text = preg_replace ('/[A-Z]/' , 'Z' , $text) ;
        $text = str_replace ('or' , 'and' , $text) ;
    }    
        
    if (  ! preg_match_all ('/\(([^\(\)]+)\)/' , $text , $matches) )
    {
        return test_ohne_klammern ($text) ;
    }

    foreach ($matches[1] as $value)
    {
        if (!test_ohne_klammern ($value)) return FALSE;
    }

    $text = str_replace ($matches[0] , 'Z' , $text) ;
    
    return test ($text , TRUE) ;
}



function test_ohne_klammern ($text) 
{
    $how_much_ands = substr_count ($text , 'and') ;
    $pattern = '/^\s*Z' ;        
    for ($n = 0 ; $n < $how_much_ands ; $n++)
    {
        $pattern .= '\s+and\s+Z' ;
    }
    
    $pattern .= '\s*$/' ;
    return preg_match ($pattern , $text) ; 
}

?>


Это сообщение отредактировал(а) NLspieler - 25.11.2009, 09:15
PM MAIL   Вверх
Simpliest
Дата 25.11.2009, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 625
Регистрация: 1.9.2009

Репутация: 1
Всего: 3



Цитата(bars80080 @  24.11.2009,  19:17 Найти цитируемый пост)
в крайнем случае для штурманского (административного) аппарата сгодится 

Лучше уж(и много проще) тогда просто дать возможность вводить любой запрос с выводом mysql_error.


--------------------
user posted image
PM   Вверх
bars80080
Дата 25.11.2009, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



Цитата(Simpliest @  25.11.2009,  08:46 Найти цитируемый пост)
Лучше уж(и много проще) тогда просто дать возможность вводить любой запрос с выводом mysql_error

вот на это я даже не знаю что сказать. просто весь прогресс цивилизации в пустую. может выкинем компьютеры, автомобили и прочее, возьмём по мотыге и удалимся все в сельское хозяйство. для жизни хватит, а что ещё надо?

так и вижу, каждый раз когда администратор смотрит на табличку с данными, красиво отстроенную с хинтами, с подсказками, с навигацией, отформатированными датами, ссылками на файлы и прочими приблудами, и вдруг ему захотелось отфильтровать данные: он закрывает таблицу, пишет унылый до невозможности запрос, а потом тупо пялится на дамп ответа, пытаясь в чёрно-белых строчках разобраться, что же он такое получил

и вы при этом носите гордое звание начальника транспортного цеха программиста!

ещё хотел добавить о космических кораблях, бороздящих просторы большого театра, но как-то к слову не пришлось
PM MAIL WWW   Вверх
Simpliest
Дата 25.11.2009, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 625
Регистрация: 1.9.2009

Репутация: 1
Всего: 3



Цитата(bars80080 @  25.11.2009,  10:02 Найти цитируемый пост)
так и вижу, каждый раз когда администратор смотрит на табличку с данными, красиво отстроенную с хинтами, с подсказками, с навигацией, отформатированными датами, ссылками на файлы и прочими приблудами, и вдруг ему захотелось отфильтровать данные: он закрывает таблицу, пишет унылый до невозможности запрос, а потом тупо пялится на дамп ответа, пытаясь в чёрно-белых строчках разобраться, что же он такое получил

Если вы гордый носитель звания блондинка,
то вам надо предоставить сторонний интерактивный генератор отчетов у которого много больше рюшечек чем в ваших таблицах, и который выдает отчет в 15ти форматах
Если же вы действительно администратор, то нужна возможность ввода произвольного SQL запроса для создания отчетов (которые буду выполняться другими пользователями-блондинками).

Попытка предположить что вы администратор недоблондинка(а в какой степени - черт его знает) выльется в полгода геморроя при создании очередного собственного велосипеда - генератора отчетов.

Ах, да, естественно что ты не смог догадаться - результат выполнения произвольного SQL запроса может выводиться не в виде дампа, а в виде таблицы с рюшечками, в XML, Excel, или просто PDF-формате.

Ты меня все больше и больше печалишь :( Тебя повысили что ли?


--------------------
user posted image
PM   Вверх
bars80080
Дата 25.11.2009, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



Цитата(Simpliest @  25.11.2009,  10:18 Найти цитируемый пост)
Если вы гордый носитель звания блондинка,
то вам надо предоставить сторонний интерактивный генератор отчетов у которого много больше рюшечек чем в ваших таблицах, и который выдает отчет в 15ти форматах

насчёт блондинки не втыкнул, но меня гложет странная уверенность, что вы не заставляете своих пользователей вносить данные, к примеру, в ленту новстей через запросы. а написали для этого определённый интерфейс, либо воспользовались чужой разработкой.
и удобность интерфейса зачастую и служит причиной выбора того или иного движка

Цитата(Simpliest @  25.11.2009,  10:18 Найти цитируемый пост)
Если же вы действительно администратор, то нужна возможность ввода произвольного SQL запроса для создания отчетов 

эту хренотень я сделал давным давно ещё при написании инструмента для работы с БД. в купе с логированием, выбором БД, разборки ответа и выдачи сообщениями с ошибоками

Цитата(Simpliest @  25.11.2009,  10:18 Найти цитируемый пост)
выльется в полгода геморроя при создании очередного собственного велосипеда - генератора отчетов.
всего две недели свободного рабочего времени

Цитата(Simpliest @  25.11.2009,  10:18 Найти цитируемый пост)
Ах, да, естественно что ты не смог догадаться 
а вот уже и откровенное оскорбление

Цитата(Simpliest @  25.11.2009,  10:18 Найти цитируемый пост)
результат выполнения произвольного SQL запроса может выводиться не в виде дампа, а в виде таблицы с рюшечками

если ещё немного подумать, то можно догадаться, что и запрос можно составлять не ввиде чернушного кода, а в табличе с рюшечками. где тебе не придётся размышлять, а что же означают данные поля, подставить в where status=1 или =0? вместо этого, можно просто кликая мышкой выбрать в падающем списке нужный статус (новый/одобрено/корзина) и получить нужную фильтрацию



Цитата(Simpliest @  25.11.2009,  10:18 Найти цитируемый пост)
XML, Excel, или просто PDF-формате

и хде я упоминал про системы отчёта? опять что-то себе придумал?
PM MAIL WWW   Вверх
bars80080
Дата 25.11.2009, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прапор творюет
****
Награды: 1



Профиль
Группа: Завсегдатай
Сообщений: 12022
Регистрация: 5.12.2007
Где: Königsberg

Репутация: 71
Всего: 315



отлично, вариант NLspieler выполняет всё как нужно

спасибо
PM MAIL WWW   Вверх
Simpliest
Дата 25.11.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 625
Регистрация: 1.9.2009

Репутация: 1
Всего: 3



Цитата(bars80080 @  25.11.2009,  10:31 Найти цитируемый пост)
что вы не заставляете своих пользователей вносить данные, к примеру, в ленту новстей через запросы. а написали для этого определённый интерфейс

В этом интерфейсе не возникает вопрос подобный твоему.


Цитата(bars80080 @  25.11.2009,  10:31 Найти цитируемый пост)
эту хренотень я сделал давным давно ещё при написании инструмента для работы с БД. в купе с логированием, выбором БД, разборки ответа и выдачи сообщениями с ошибоками
всего две недели свободного рабочего времени

Вполне очевидно, что у меня длиннее - потребовалось всего 3 дня. 
Но я вполне отдают отчет что это и рядом не стояло с Crystal Reports, Fast Reports etc.

Цитата(bars80080 @  25.11.2009,  10:31 Найти цитируемый пост)
вместо этого, можно просто кликая мышкой выбрать в падающем списке нужный статус (новый/одобрено/корзина) и получить нужную фильтрацию

Нормальному админу это бесполезно. Потому что любой функционал который ты можешь написать за две недели - убог.
(я тоже за это время не напишу ничего выдающегося, но это не оправдание для тебя)
А действительно нужный функционал ты не реализовал.

Цитата(bars80080 @  25.11.2009,  10:31 Найти цитируемый пост)
и хде я упоминал про системы отчёта? опять что-то себе придумал? 

Да нигде.
Ты просто невнимательно читаешь. Весь список родился как напоминание, что смотреть на голый дамп - не обязательно.
При правильном проектировании результаты выполнения любого запроса можно вывести в любом удобном (и поддерживаемом системой) формате. Впрочем, - помня о твоих шаблонах, - да, для твоего приложения это может быть сложностью. Но ты сам себе ее создал.

Тем не менее...
Вот это
Цитата(bars80080 @  24.11.2009,  14:20 Найти цитируемый пост)
значит, есть у нас строка

$str = '(A and B) or C';

эта строка пойдёт в запрос:

Имеет смысл в двух местах - репортинговой системе или ОРМ. Писать и то и другое - достаточно глупо.
Еще более странно если "это" потребовалось в другом месте приложения.


--------------------
user posted image
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0629 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.