PHP поиск по многомерному массиву.

Graf_Vorontsov

Новичок
Делаю поиск (он ещё пока не окончен полностью, но работает уже с частью номеров которые хочу искать).

Файл 33.csv содержит каталожные номера с ценами и названиями.
Имеется форма поиска в которую вводится искомый номер детали(она в отдельном файле).
хотел бы получить маленькую консультацию у знатоков. Заранее спасибо.
PHP:
<?php
    $handle = fopen("33.csv", "r");
    echo "<center><table width=40% border=1 cellspacing=0 cellpadding=2>";
    echo "<caption>Наличие запчастей на складе</caption>";
    echo "<tr><td>Оригинальный №</td><td>Неоригинальный №</td><td>Наименование</td><td>Производитель</td><td>Цена</td></tr>";
    while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {

        echo "<tr>";
        //проверка на наличие в строке определённых символов
        if (strstr($_REQUEST['number'],'01C')){
            $return = preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d+]{3})\s*([\w]{1,2})?\s*([\w\d]{3})*$/si', '$1 $2 $3 $4 01C', $_REQUEST['number']);
            $return = str_replace("  "," ", $return);     
        // если код 01C
        } elseif (strstr($_REQUEST['number'],'2ZZ')){
            $return = preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d+]{3})\s*([\w]{1,2})?\s*([\w\d]{3})*$/si', '$1 $2 $3 $4 2ZZ', $_REQUEST['number']);
            $return = str_replace("  "," ", $return);          
        // если код 2ZZ
        } elseif (strstr($_REQUEST['number'],'2ER')){
            $return = preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d+]{3})\s*([\w]{1,2})?\s*([\w\d]{3})*$/si', '$1 $2 $3 $4 2ER', $_REQUEST['number']);
            $return = str_replace("  "," ", $return);          
        // если код 2ER
        } else 
        //во всех остальных случаях без кода цвета
        $return = preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d]{3})\s*([\w]{1,2})?\s*$/si', '$1 $2 $3 $4', $_REQUEST['number']);
                 
        foreach($data as $value) {                      
            if(in_array((strtoupper(trim($return))), $data)) {
            //проверка. введены ли данные в поле поиска
                if (!empty($return)and isset($return)){  
                                  
                    echo "<td>$value</td>"; //если введены данные, выдать найденый результат
                } else {
                    exit("<br><h2><font color=red>Вы ничего не ввели </font></h2><br /><br />"); //если ничего не ввели в поле поиска
                }
 
            }
              
        }
        echo "</tr>";
   }
   echo "</table></center>";
   fclose($handle);
?>
1) как можно в регулярном выражении записать жёсткое соответствие конкретным символам(например мне надо проверять есть ли в строке 357256222RE01C конкретная последовательность символов в данном случае 01C, эти символы всегда в конце, их всегда 3, но они могут быть и разными напр. 2ZZ, 1UT).
пытался писать так
PHP:
preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d]{3})\s*(\w{1,2})*\s*(01C|2ZZ$)*/si', '$1 $2 $3 $4 $5', $request_number);
вот этим (01C|2ZZ$) я пытался сделать выбор..но как-то не так работает! Т.к. предыдущий аргумент может быть или 357256222RE01C или 357256222E01C(т.е. или RE присутствует или только E). И мне выводит не то шо надо. Скрипт начинает игнорировать 4-й аргумент.... Пришлось побороть такой конструкцией:
PHP:
if (strstr($_REQUEST['number'],'01C')){
             $return = preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d+]{3})\s*([\w]{1,2})?\s*([\w\d]{3})*$/si', '$1 $2 $3 $4 01C', $_REQUEST['number']);
             $return = str_replace("  "," ", $return);
но это как-то на мой взгляд через ж*** :) Может есть цивилизованное решение?

2) В мануале пишут что preg_replace может содержать регулярное выражение и в шаблоне поиска и в шаблоне подстановки... Я почемуто не пойму как заставить работать регулярку в шаблоне подстановки.
И где можно почитать конкретно про правила написания шаблона подстановки?

3) Я так и не понял как можно сравнить значения если символ не дописан?! Т.е по регулярке он прошёл, записался в $return , а дальше сравнивается с моими значениями в массиве

PHP:
if(in_array((strtoupper(trim($return))), $data))
и не проходит потому что символ не дописан. Как этого избежать? Т.е. как заставить искать все совпадения до конкретного символа?
 

Graf_Vorontsov

Новичок
результат отстаётся тот же.
выводится аргументы $1 $2 $3 $4(не выводится вообще) $5(а тут остаётся только одна или две(в зависимости от того сколько символов содержит $4) последняя буква или цифра). Не пойму в чём загвоздка....
 

Graf_Vorontsov

Новичок
ура!! первый вопрос я победил, подправив немного регулярку
с этого
PHP:
preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d]{3})\s*(\w{1,2})*\s*(01C|2ZZ$)*/si', '$1 $2 $3 $4 $5', $_REQUEST['number']);
на это
PHP:
preg_replace('/^([\w\d]{3})\s*([\d]{3})\s*([\d]{3})\s*(\w{1,2})?\s?(01C|2ZZ|1Y8)?$/si', '$1 $2 $3 $4 $5', $_REQUEST['number']);
остались ещё вопросики...
 

tz-lom

Продвинутый новичок
2 - это какой то бред, где вы такое нашли
3 - по чётче выражайте свои мысли, я ничего не понял
 

Graf_Vorontsov

Новичок
2. (вот тут нашёл) http://web.ixit.ru/php/tutorial/part08.shtml
preg_replace()

Функция preg_replace() работает точно так же, как и ereg_replace(), за одним исключением — регулярные выражения могут использоваться в обоих параметрах, шаблон и замена. Синтаксис функции preg_replace():

mixed preg_replace (mixed шаблон, mixed замена, mixed строка [, int порог])

Необязательный параметр порог определяет максимальное количество замен в строке. Интересный факт: параметры шаблон и замена могут представлять собой масивы. Функция preg_replace() перебирает элементы обоих массивов и выполняет замену по мере их нахождения.
3. В массиве записана сторока 338 256 358 J и 338 256 358 JM и 338 256 358
я ввожу в поле поиска 338 256 358 мне выдаст только последнее число, а надо чтоб все три.
 

Graf_Vorontsov

Новичок
2. спасибо буду изучать! А то попадаеться какая-то левая документация и сбивает с пути истинного :)
3. а по поводу регулярки - так у меня и так она написана так чтоб последние аргументы были не обязательны(может я ошибаюсь....)
но не понимаю как сравнить полученное значение с тем что лежит в массиве.... ведь соответствие неполное...
 

tz-lom

Продвинутый новичок
3 - убери ^ и $ , тогда она будет выдавать все результаты в которых нашлась заданная последовательность (и не важно что за/перед ней)
 

Graf_Vorontsov

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

может как-то нужно сравнить $return(полученная строка) и $data(это массив) и при определённом совпадении вывести $value(найденные значения массива)
 

A1x

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

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

tz-lom

Продвинутый новичок
PHP:
        foreach($data as $value) {                      
            if(in_array((strtoupper(trim($return))), $data)) {
            //проверка. введены ли данные в поле поиска
                if (!empty($return)and isset($return)){  
                                  
                    echo "<td>$value</td>"; //если введены данные, выдать найденый результат
                } else {
                    exit("<br><h2><font color=red>Вы ничего не ввели </font></h2><br /><br />"); //если ничего не ввели в поле поиска
                }
 
            }
              
        }
?>
это снести и переписать,оно похоже на поиск только первым циклом
внутри должно быть сравнение с регуляркой/ поиск подстроки как подсказывают выше , ну и действия по результату
 

Graf_Vorontsov

Новичок
по поиску подстроки - чёт я не пойму с чего начать... ну буду щас думать.............
 

Graf_Vorontsov

Новичок
народ, помогите -- не соображу
пробовал similar_text... бред получается
PHP:
           similar_text ($return, $value, $similar);
            if ($similar > 80){
            echo "<td>$value</td>"; //если введены данные, выдать найденый результат

            break;
            }
 

Graf_Vorontsov

Новичок
да да, понятно, я ж говорю не пойму как реализовать!! Ну хоть пример дайте какой... только не на словах а реальный ПХП пример :)
я какбы логически понимаю что надо делать а вот каким образом..??!
 

tz-lom

Продвинутый новичок
хмм... ну ок,в порядке исключения, хотя мне кажется кто то крайне ленится читать доку и думать
PHP:
if(strpos( подставь параметры один - твоя строка в которой ты ищешь ID  , другой - твой ID ) !== false) { // он в ней есть }
нет,не смог лишить тебя шанса заглянуть в маны
заодно посмотри что такое === и !==
 

Graf_Vorontsov

Новичок
Спасибо :)

Оператор сравнения ==
$a === $b Тождественно равно TRUE если $a равно $b и имеет тот же тип.
$a != $b Не равно TRUE если $a не равно $b.
$a == $b Равно TRUE если $a равно $b.
$a !== $b Тождественно не равно TRUE если $a не равно $b или в случае, если они разных типов

немного не пойму что значит имеют тот же тип...
мой ID это понятно $return , а строка в которой ищу получается $value ?
значит мне не нужна строка if(in_array((strtoupper(trim($return))), $data)) ?или я ошибаюсь.... ну ладно погнал пробовать.
 

Graf_Vorontsov

Новичок
получилось чтоб находило неполное вхождение вот так(уже радует,... но не очень)
так выводит но только первый столбик()
PHP:
foreach($data as $value) {   
    if (strpos( $value  , $return ) !== false){            
        $found_value=$value; 
        echo "<td>$found_value</td>";   
    }
}
результат выводится как-то неправильно! а та запись что была у меня... эта
PHP:
foreach($data as $value) {   
            if(in_array((strtoupper(trim($return))), $data)) {                
                    echo "<td> $value</td>"; 
            }
}
выводила так (321 615 303 E 01C 24.0120-0129.1 Диск тормознойATE 333,84), т.е. полностью строку как и записано в файле.

написал так:
PHP:
foreach($data as $value) {   
    if (strpos( $value  , $return ) !== false){            
        $found_value=$value; 
        echo "<td>$found_value</td><td>$data[1]</td><td>$data[2]</td><td>$data[3]</td><td>$data[4]</td>";
    }
}
да, если вводить в строку поиска значение которое стоит первым, то нормально остальные достраиваються, а если ввести второе, в данном случае "24.0120-0129.1 ", то оно записывается в первый элемент и во второй(т.е. пропадает значение из первой колонки)
321 615 303 E 01C 24.0120-0129.1 Диск тормозной ATE 333,84


не пойму как совместить их.... Вот такая беда.

для наглядности прилагаю картинки
 

Вложения

  • 84 KB Просмотры: 2
  • 64,1 KB Просмотры: 2
Сверху