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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация кода поиска по CSV, Сделал скрипт, но что-то в нём не хватае 
:(
    Опции темы
Mafiosi
Дата 23.2.2012, 01:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



1. есть csv файл в котором находятся номера автозапчастей.
2. Есть форма поиска, в которую пользователь вбивает искомый номер
3. Есть скрипт, который проверяет то что ввёл пользователь с тем что хранится в файле csv и выдаёт результат: есть искомая запчасть или нет.

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

preg_match
//и
preg_replace

для того чтоб по шаблону подстроить данные введённые пользователем под то что храниться в файле.
Как сделать это без регулярных выражений я пока не врублюсь, конечно посмотрев на мой скрипт, можно упасть в обморок от того сколько там регулярок smile , но .... работает ведь оно smile)
Вобщем: 
1. Хотел бы конечно каким-то образом оптимизировать скрипт с моими регулярками, может вообще от них избавится....
2. Или подскажите что в нём не хватает чтоб искало по всем шаблонам, я не пойму... находит по одному шаблону, далее передаёт на сравнение и всё - скрипт большге не сравнивает,а хотелось бы чтобы он искал все похожие значения и подставлял по очереди в форму сравнения найденый результат, а номера есть похожие, только отличаются например пробелами. Вот пример (2 339 303 222 и 1864 528 441) - тут одинаковое количество цифр, но пробелы расположены по разному(это разные фирмы запчастей) и в файле они так хранятся и выводить на экран надо также - пользователь вводить может эти номера не взирая на пробелы вообще. Вот я и расставляю пробелы с помощью preg_replace так как надо и полученое значение сравниваю со значением в файле csv. 
Не знаю правильно ли всё разъяснил... Но вот кусок кода что меня мучает:
Код

        if (!empty($_REQUEST['number'])and isset($_REQUEST['number'])and(strlen($_REQUEST['number']) >= 4)){ 
            
        //если введены данные, выполняеся поиск
              
            //удаляем пробелы в начале и в конце строки, переводим все символы в верхний регистр  
              
            $_REQUEST['number'] = strtoupper(trim($_REQUEST['number']));
        
            //проверка на наличие в строке определённых символов
            // для жидкостей, гермета, метизов
            
            if (preg_match('/^(G|D|N)\s*([\d]{3})\s*([\w\d]{3})\s*([\w\d]{1,2})*$/si', $_REQUEST['number'])){
                $return = preg_replace('/^(G|D|N)\s*([\d]{3})\s*([\w\d]{3})\s*([\w\d]{1,2})*$/si', '$1 $2 $3 $4', $_REQUEST['number']);   
            }elseif 
 
            //для Sachs
                        
            (preg_match('/^([\d]{4})?\s?([\d]{3})\s?([\d]{3})$/si', $_REQUEST['number'])){
                $return = preg_replace('/^([\d]{4})?\s?([\d]{3})\s?([\d]{3})$/si', '$1 $2 $3', $_REQUEST['number']);
                $return = trim($return);                
            }elseif
            
            //для Luk, INA ***путается с оригиналом
        
            (preg_match('/^(INA|LUK)\s?([\d]{3})\s?([\d]{4})?\s?([\d]{2})$/si', $_REQUEST['number'])){
                $return = str_ireplace('INA', '', $_REQUEST['number']);   
                $return = str_ireplace('LUK', '', $_REQUEST['number']);    
                $return = preg_replace('/^(INA|LUK)\s?([\d]{3})\s?([\d]{4})?\s?([\d]{2})$/si', '$2 $3 $4', $_REQUEST['number']);
            }elseif   
            
            //для Swag  ***путается с оригиналом
            
            (preg_match('/^(SW)\s?([\d]{2})\s?([\d]{2})\s?([\d]{2})\s?([\d]{2})$/si', $_REQUEST['number'])){
                $return = preg_replace('/^(SW)\s?([\d]{2})\s?([\d]{2})\s?([\d]{2})\s?([\d]{2})$/si', '$2$3$4$5', $_REQUEST['number']); 
                $return = str_ireplace('SW', '', $_REQUEST['number']);
            }elseif  

            //для KS, Tecnodelta
        
            (preg_match('/^(77|85|78|79|87|93)\s?([\d]{3})\s?(600|610|620|604|112|012)$/si', $_REQUEST['number'])){
                $return = preg_replace('/^(77|85|78|79|87|93)\s?([\d]{3})\s?([\d]{3})$/si', '$1 $2 $3', $_REQUEST['number']);                     
            }else
            
                //оригинальные номера с кодом цвета
                  
                $return = preg_replace('/^([\w\d]{1,3})\s?([\w\d]{3})\s*([\w\d]{3})?\s*([\w\d]{1,3})?\s?(01C|091|B41|GLB|RDW|GRU|03C|5WK|9XK|1YX|E64|B98|041|25R|Z17|GJW|V7L|MFX|FED|7ZC|2BC|Z37|RGZ|7ZJ|2ZZ|909|9B9|5YX|001|A94|3FZ|EMD|7DL|A21|2VK|FEF|20H|FDY|GX2|DRR|FCS|QN5|WM7|Z10|739)*$/si', '$1 $2 $3 $4 $5', $_REQUEST['number']);               
                //$return = preg_replace('/^([\d]{8})$/si', '$1', $_REQUEST['number']);
                $return = str_replace("  "," ", $return);
                $return = chop($return);             

            //ищем номер в массиве данных 
                   
            foreach($data as $value) { 
                
                if (strpos( $value  , $return ) !== false){ 
                    
                    //вывод результата в виде таблицы 
                    
                    echo "<td style='padding: 6px;'>$data[0]</td><td style='padding: 6px;'>$data[1]</td><td style='padding: 6px;'>$data[2]</td><td style='padding: 6px;'>$data[3]</td><td style='padding: 6px;'>$data[4]</td><td style='padding: 6px;'>$data[5]</td>"; //если введены данные, выдать найденый результат                          
                }
                
            }
      
        }else {
            
            //если ничего не ввели в поле поиска
                        
            exit("<center><br><h2><font color=red>Вы ничего не ввели </font></h2><br /><br /></center>");            
        
        }


извините за большой код, но хотел показать хоть пару примеров регулярки(это далеко не все... их штук 40 разных). Пришлось в коментариях к форме поиска написать чтоб пользователь перед определёнными номерами вводил начальные идентификаторы(SW, INA, LUK) чтоб скрипт понял по какой регулярке ему сравнивать, может это не правильно..!?.... направте на путь smile

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

нашёл тему очень похожую на мою ситуацию, но там отсутствует "фактор свободного поведения пользователя" smile
http://forum.vingrad.ru/topic-27376.html
у меня отличается.
PM MAIL WWW ICQ   Вверх
skyboy
Дата 23.2.2012, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



можешь привести пример файла и пример запроса?

Добавлено @ 14:24
Цитата(Mafiosi @  23.2.2012,  00:11 Найти цитируемый пост)
Я думал может удалять все лишние символы с файла и с формы поиска, думаю так будет проще сделать поиск не взирая на пробелы и точки и тире, но как сделать чтоб вывод результата был красивый, т.е. изначально хранящийся в файле..

вот это-то как раз просто: сравниваешь "урезанные" варианты, а выводишь - нормальный, полноценный
Код

$normalize = function ($phone) {
 return ltrim((preg_replace("#\D#", "", $phone)), '0');
};
$lines = array("(096)71-20-123","032-213-45-65","0-800-900-900");
$search = "096-321745";
$filtered = array_filter($lines, function($item) use ($search, $normalize) {
    return $normalize($item) == $normalize($search);
}); 
foreach($filtered as $phone) {
 echo $phone . '<br />';
}

как-то так
PM MAIL   Вверх
Mafiosi
Дата 23.2.2012, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот кусок из файла
Код

06B 198 141;623 3097 00;Комплект сцепления на AWT,AEB;Luk;1021.12;Есть в наличии
06B 129 717 A;71-34208-00;Прокладка;Victor Reinz;34.44;Есть в наличии
06B 109 243 B,E;EVR55496;Ролик;Ruville;402.1;Есть в наличии
06B 198 151 B;08-502900-00;Кольца;Goetze;180.87;Есть в наличии
06C 133 843;AP 179/2;Фильтр;Filtron;82.62;Есть в наличии
4A1 721 401;6284 004 031;Цилиндр;Sachs;940.9;Есть в наличии
701 698 151 G;GDB 791;Колодки;TRW;369.72;Есть в наличии
701 698 151 C;13.0460-2972.2;Колодки;ATE;681.07;Есть в наличии

а вот такой запрос могут вводить пользователи, по каждой позиции пример

06B129717A
623309700
713420800
55496
0850290000
13046029722
или бывает ставят некоторые символы, но не все... пользователя тяжело заставить писать так как в каталоге написан номер smile
PM MAIL WWW ICQ   Вверх
skyboy
Дата 23.2.2012, 14:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



угу, понятно.
ну, тогда совет прежний: сравнивай нормализованное, выводи - как есть.
PM MAIL   Вверх
Mafiosi
Дата 23.2.2012, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Fatal error: Function name must be a string in 
Код

$filtered = array_filter($lines, function($item) use ($search, $normalize) {


вот такое пишет 
PM MAIL WWW ICQ   Вверх
skyboy
Дата 23.2.2012, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



closure только в 5.3 ввели.
ну, ты по коду понимаешь, что где происходит?
отдельно отобрали и вывели исходные, не измененные строки.

PM MAIL   Вверх
Mafiosi
Дата 23.2.2012, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Код

$normalize = function ($phone) {
 return ltrim((preg_replace("#\D#", "", $phone)), '0');

тут не пойму что такое '0'
Код

$lines = array("(096)71-20-123","032-213-45-65","0-800-900-900");
$search = "096-321745";
$filtered = array_filter($lines, function($item) use ($search, $normalize) {

тут почему function($item) почему не function($phone)
и
конструкция use ($search, $normalize) не пойму как работает
Код

    return $normalize($item) == $normalize($search);

а тут тоже почему $item а не $phone
PM MAIL WWW ICQ   Вверх
skyboy
Дата 23.2.2012, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



closures in PHP
изивини, похоже, я тебя запутал.
давай, забудем и сделаем по-другому:
Код

function normalize_phone($phone) {
 return ltrim((preg_replace("#\D#", "", $phone)), '0');
};
function are_phones_equal($phone1, $phone2) {
 return normalize_phone($phone1) == normalize_phone($phone2);
}
$lines = array("(096)71-20-123","032-213-45-65","0-800-900-900");
$search = "096-321745";
foreach($lines as $candidate) {
 if (are_phones_equal($candidate, $search))
  echo $candidate . '<br />';
}


Добавлено через 2 минуты и 21 секунду
Цитата(Mafiosi @  23.2.2012,  14:51 Найти цитируемый пост)
тут не пойму что такое '0'

вырезать лидирующий ноль.
некоторые у нас его опускают при записи: "096-333-22-11" превращается в "96-333-22-11". реально встречал smile
потому решил для демонстрации поиска тоже его вырезать, но именно если он в первой позиции стоит.
PM MAIL   Вверх
Mafiosi
Дата 23.2.2012, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ноль как раз мне вырезать не надо, я сделал так 'EVR' - это забывают часто или пишут вместо него RU
как в эту функцию добавить ещё исключений немного(более одного) или чтоб заменяло например RU на EVR если в поиске вписали такое
пробовал так: добавлял строку в функцию... но почему-то не работает
Код

//return str_ireplace("EVR", "", $data_corected);

Код

    function normalize_phone($data_corected) {
        return ltrim((preg_replace("#\W#", "", $data_corected)), 'EVR');
        //return str_ireplace("EVR", "", $data_corected);
    };

регулярку поставил \W т.к. у меня кроме пробелов есть ещё точки и тире...., но и буквы есть в номерах - так что буквы удалять нельзя smile

и у меня в скрипте поиск был с помощью этой функции strpos
Код

//if (strpos( $value  , $return ) !== false){ 

она находит вхождение части символов в строку, т.е. человек может вписать в поле поиска номер 8L0601165D вместо 8L0 601 165 D 7ZJ и найдёт это значение... не пойму куда прикрутить теперь эту функцию.

А так скрипт ваш работает очень даже хорошо!!! smile
PM MAIL WWW ICQ   Вверх
Mafiosi
Дата 25.2.2012, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ааа!!! сделал! работает. вот так:
ltrim убрал за ненадобностью.
и вместо == сделал strstr
Код

    function normalize_phone($data_corected) {
        return preg_replace("#\W#", "", $data_corected);
    };
    function are_phones_equal($number1, $number2) {
        return strstr(normalize_phone($number1), normalize_phone($number2));
    }


спасибо за помощь!!!!!! 

Это сообщение отредактировал(а) Mafiosi - 25.2.2012, 15:37
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

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

Важно:

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

Внимание:

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

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

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


 




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


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

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