ФорумПрограммированиеPHP для идиотов → как лучше сделать, регулярками или поиском по строке?

как лучше сделать, регулярками или поиском по строке?

  • developer

    Сообщения: 241 Репутация: N Группа: Кто попало

    Spritz 23 марта 2011 г. 8:14

    есть прайс xls вида:
    Шина 155/65R13 Sno-Max(ш.) 73Q Cordiant
    Шина 155/70R13 Meteo Grip E+(пш) 75Q Marangoni
    Шина 155/70R13 Meteo Grip E+(ш.) 75Q Marangoni
    Шина 145/70R13 A.drive AA01 71T Yokohama
    Шина 145/70R13 Altimax RT 71T General Tires
    Шина 145/70R13 330 71T Toyo
    Шина 155/65R13 Comfort 82T Cordiant
    Шина 155/65R13 EcoControl 73T Fulda


    распарсил xls, получил три колонки: наименование | кол-во | цена

    хочу сделать обновление цены в базе с проверкой по параметрам, нужно разделить строку выше: {шины - это раздел} {ширина}/{высота}{Raдиус} {модель} ({сезон}) {индекс нагрузки} {бренд}

    как лучше сделать, разбить это всё дело регулярками и потом делать проверку? но бывают проблемы с тем что кое-где из строк указаны не все параметры: Шина 155/65R13 Passio2 Debica или Шина 155/R13 Hakka 91Q Nokian
    или указано слишком много ненужных параметров: Шина 185/65R14 Ice Cruiser 5000(пш) (WC50PZ) 86T Bridgestone или Шина 165/70R14C KC11 89/87Q Kumho
    или в другом порядке попадаются параметры, например: Шина 205/70R16 Кама-Flame 91Q б/к

    думал сделать список всех параметров, поместить каждый в отдельный array:

    $brand = array("Cordiant", "Marangoni", "Yokohama", "General Tires", "Toyo", "Debica", "Kumho", "Fulda", "Sava", "Dunlop", "GoodYear", "Hankook", "Barum", "Roadstone", "Trayal");
    $size = array("155/65R13", "155/70R13", "145/70R13", "155/65R13", "155/65R13");
    $ind = array("86T", "73T", "82T", "75Q", "71T");
    …..


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

    пытался с помощью preg_match:
    $isExists = preg_match("/$find/s", $cellval);

    но не получилось, неужели по каждому из параметров нужно цикл делать?

    может кто подскажет верный путь.
  • Givi

    Сообщения: 2284 Репутация: N Группа: Адекваты

    Spritz 23 марта 2011 г. 8:43, спустя 29 минут 37 секунд

    думаю не все так просто, ибо та же модель может как захочешь называться: с одного слова, двумя словами, буквами-цифрами и т.д. Вот с этим как минимум возникнут траблы, ибо система не сможет понять название ли это модели или уже индекс скорости (или другой какой-то параметр). Особенно с учетом того, что в прайсе все записи не имеют какой-то систематики.
    п.с. Когда-то разбирали такие прайсы в 200-250 позиций простым единоразовым вносом каждой позиции в базу и последующую сверку с базой. Если позиции в базе не было, то она "откладывалась" до конца обработки прайсов и в результате мы имели обновление всего что есть + список новых строк, которые нужно довнести вручную. Но это частный случай.
  • developer

    Сообщения: 241 Репутация: N Группа: Кто попало

    Spritz 23 марта 2011 г. 9:57, спустя 1 час 14 минут


    думаю не все так просто, ибо та же модель может как захочешь называться: с одного слова, двумя словами, буквами-цифрами и т.д. Вот с этим как минимум возникнут траблы, ибо система не сможет понять название ли это модели или уже индекс скорости (или другой какой-то параметр). Особенно с учетом того, что в прайсе все записи не имеют какой-то систематики.
    п.с. Когда-то разбирали такие прайсы в 200-250 позиций простым единоразовым вносом каждой позиции в базу и последующую сверку с базой. Если позиции в базе не было, то она "откладывалась" до конца обработки прайсов и в результате мы имели обновление всего что есть + список новых строк, которые нужно довнести вручную. Но это частный случай.


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

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

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 23 марта 2011 г. 10:32, спустя 34 минуты 47 секунд

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

    155/65R13 - тебе отсюда нужен только диаметр плюс оставляешь маркировку целиком:
    155/65R13
    13
    т.е. ни ширину ни профиль выдёргивать смысла нет, хотя и не помешает

    R - это не радиус, а тип каркаса (радиальный)

    можешь в итоге собрать полную маркировку - 155/65R13 73Q
    не всё полезно, что в swap полезло
  • md5

    Сообщения: 11949 Репутация: N Группа: в ухо

    Spritz 23 марта 2011 г. 10:41, спустя 8 минут 30 секунд

    R - это не радиус, а тип каркаса (радиальный)

    да ладно? Оо
    все умрут, а я изумруд
  • master

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 23 марта 2011 г. 10:45, спустя 4 минуты 3 секунды

    md5, на правах пруфлинка
    http://wheel1000size.ru/
    http://www.nankangtire.ru/
    И я даже вики правил, как раз раздел маркировка http://ru.wikipedia.org/wiki/Автомобильная_шина#.D0.9C.D0.B0.D1.80.D0.BA.D0.B8.D1.80.D0.BE.D0.B2.D0.BA.D0.B0
    не всё полезно, что в swap полезло
  • md5

    Сообщения: 11949 Репутация: N Группа: в ухо

    Spritz 23 марта 2011 г. 10:49, спустя 3 минуты 56 секунд

    master, круто) спс
    все умрут, а я изумруд
  • Troy

    Сообщения: 2532 Репутация: N Группа: Джедаи

    Spritz 23 марта 2011 г. 11:29, спустя 39 минут 54 секунды

    Пыха то место. где даже царь школоты эпсил узнает что-то новое
  • developer

    Сообщения: 241 Репутация: N Группа: Кто попало

    Spritz 23 марта 2011 г. 11:29, спустя 36 секунд

    спасибо. вообщем получилось отделить сначала бренд, потом размер, теперь в строке осталась модель, индекс скорости и нагрузка.
    нужно отделить индекс скорости и нагрузку, в основном это 2 цифры и буква, например: 75Т или 75Q или 104S и т.д.
    но попадаются и такие экземпляры: 89/87Q или 104/102S
    какой регуляркой можно обучить и то и то выдирать?

    и ещё вопрос, к master скорее всего, больше разбираешься видимо: Hakka Green 95Т XL, что такое XL?
  • master

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 23 марта 2011 г. 11:32, спустя 3 минуты 8 секунд

    developer, http://en.allexperts.com/q/Tires-2359/2008/9/xl-tires-lt-tire.htm
    не всё полезно, что в swap полезло
  • developer

    Сообщения: 241 Репутация: N Группа: Кто попало

    Spritz 23 марта 2011 г. 11:56, спустя 24 минуты 7 секунд

    сделал так:
    preg_match_all( "/([0-9]{2,3}[A-Z]{1})|([0-9]{2,3}\/[0-9]{2,3}[A-Z]{1})/i", $cellval, $ind);

    вроде работает, но! заметил что пропустило такую строку "MP15 79Т" и "4 Winter 88Т", "4 Winter 88Т", "Kristal Montero 79Т" и ещё несколько, в чём ошибка регулярки?
  • master

    Сообщения: 3236 Репутация: N Группа: Джедаи

    Spritz 23 марта 2011 г. 12:02, спустя 5 минут 57 секунд

    developer, может быть что угодно, вплоть до букв в разных раскладках, например вместо "x" английской будет "х" русская
    напиши ещё одно условие, в чём проблема?
    не всё полезно, что в swap полезло
  • developer

    Сообщения: 241 Репутация: N Группа: Кто попало

    Spritz 23 марта 2011 г. 12:46, спустя 43 минуты 27 секунд

    точно, не подумал про раскладку.
    сделал так:
    preg_match_all( "/([0-9]{2,3}[A-ZА-Я]{1})|([0-9]{2,3}\/[0-9]{2,3}[A-ZА-Я]{1})/i", $cellval, $ind);


    осталось решить проблему с тем что выдирать выдирает, но вместо букв символ: �
  • developer

    Сообщения: 241 Репутация: N Группа: Кто попало

    Spritz 23 марта 2011 г. 13:13, спустя 27 минут 8 секунд

    всё, решил, выкладываю исходник, вдруг кому пригодится:
    $find = array("Marangoni", "Yokohama", "General Tires", "Toyo", "Debica", "Kumho", "Fulda", "Sava", "Dunlop", "GoodYear", "Hankook", "Barum", "Roadstone", "Trayal", "Maxxis", "Avon", "Tigar", "Lassa", "Continental", "Gislaved", "Nexen", "Bridgestone", "Matador", "Nokian", "Kingstar", "Autoguard", "Michelin", "BFGoodrich", "Starfire", "Firenza", "Sportiva", "Cooper", "Zeetex", "Mabor", "Kleber", "Firestone", "Кама", "Бел");

    foreach($find as $found) {
    preg_match("/".$found."/", $cellval, $matches);
    if(count($matches) > 0) {
    $new = explode(" ", $cellval);
    preg_match_all( "/([0-9]{3})\/([0-9]{2})(.*)/i", $new[1], $cellval_exit);

    $cellval = str_replace($cellval_exit[1][0] . '/' . $cellval_exit[2][0] . $cellval_exit[3][0], '', $cellval); // убираем размер из строки
    $cellval = str_replace($matches[0], '', $cellval); // убираем бренд из строки

    $cellval_exit[3][0] = str_replace("R", "", $cellval_exit[3][0]); // убираем R из радиуса

    preg_match_all( "/([0-9]{2,3}[A-ZА-Я]{1})|([0-9]{2,3}\/[0-9]{2,3}[A-ZА-Я]{1})/iu", $cellval, $ind);

    $cellval = str_replace($ind[0][0], "", $cellval); // убираем индекс нагрузки и скорости из радиуса

    $cellval = $cellval . ' = ' . $cellval_exit[1][0] . ' - ' . $cellval_exit[2][0] . ' - ' . $cellval_exit[3][0] . ' - ' . $ind[0][0] . ' - ' . $matches[0];

    print_r($match);
    }
    }


    с помощью этого кода в конечном итоге получаем:
    Meteo Grip E = 155 - 70 - 13 - 75Q - Marangoni
    Perfecta = 155 - 70 - 13 - 75T - Sava
    K715 = 155 - 70 - 13 - 75T - Hankook
    KH17 = 155 - 70 - 13 - 75Т - Kumho
    Regio Control = 215 - 75 - 17.5 - 126/124M - Fulda
    и так далее… Тоесть модель = ширина - высота - радиус - индекс скорости и нагрузки - бренд.
    решения другого не нашёл. что будет с новыми брендами так же не знаю.
  • developer

    Сообщения: 241 Репутация: N Группа: Кто попало

    Spritz 1 апреля 2011 г. 9:21, спустя 8 дней 20 часов 7 минут

    Снова проблема, точнее не проблема, а хотелось бы оптимизировать код.:
      		for($i=0; $i < count($hr); $i++) {
    $siska = explode(";", $hr[$i]);
    $query = mysql_query("select p.productID, p.name, c.optionID, c.productID, c.option_value from ".$main['prefix']."products p, ".$main['prefix']."product_options_values c where p.name = '" . $siska[0] . "' and c.productID = p.productID and c.optionID = 5 and c.option_value = '". $siska[3] ."'");

    while ($row = @mysql_fetch_array($query)) {
    if(!empty($row['option_value'])) {
    $query_otp4 = mysql_query("select optionID, productID, option_value from ".$main['prefix']."product_options_values where optionID = '4' and productID = '" . $row['productID'] . "'");
    while ($row_otp4 = @mysql_fetch_array($query_otp4)) {
    $opt1 = $row_otp4['option_value'];
    }
    $query_otp7 = mysql_query("select optionID, productID, option_value from ".$main['prefix']."product_options_values where optionID = '7' and productID = '" . $row['productID'] . "'");
    while ($row_otp7 = @mysql_fetch_array($query_otp7)) {
    $opt2 = $row_otp7['option_value'];
    }
    $query_otp8 = mysql_query("select optionID, productID, option_value from ".$main['prefix']."product_options_values where optionID = '8' and productID = '" . $row['productID'] . "'");
    while ($row_otp8 = @mysql_fetch_array($query_otp8)) {
    $opt3 = $row_otp8['option_value'];
    }
    $query_otp1 = mysql_query("select optionID, productID, option_value from ".$main['prefix']."product_options_values where optionID = '1' and productID = '" . $row['productID'] . "'");
    while ($row_otp1 = @mysql_fetch_array($query_otp1)) {
    $opt4 = $row_otp1['option_value'];
    }

    if($opt2 == $siska[1] AND $opt3 == $siska[2]) {
    $sql = "UPDATE ".$main['prefix']."products SET Price = '".$siska[7]."', in_stock = '".$siska[6]."' WHERE productID = '".$row['productID']."'";
    $result = mysql_query($sql) or die(mysql_error());

    echo '<a href="http://site/-/p' . $row['productID'] . '/">' . $row['productID'] . '</a> => ' . $row['name'] . '|' . $opt1 . '|' . $opt2 . '|' . $opt3 . '|' . $row['option_value'] . '|' . $opt4 . ' => ' . $siska[0] . '|' . $siska[5] . '|' . $siska[1] . '|' . $siska[2] . '|' . $siska[3] . '|' . $siska[8] . ' - обновлены цена и наличие<br />';

    unset($hr[$i]);
    fputs(fopen('price/' . $filename . '.csv','w+'),implode("",$hr));
    }

    }

    }


    }

    а конкретнее ту часть где идут запросы $query_otp4, $query_otp7, $query_otp8, $query_otp1
    они ищут значения из одной и той же таблицы, но в разных строках. Можно ли как-то дополнить $query чтобы сразу, одним запросом производить поиск по нескольким строкам в таблице? или для mysql это слишком?
    потому что для MS SQL есть FOR XML PATH, а тут хз. может кто сталкивался с такой озабоченой структурой базы?

Пожалуйста, авторизуйтесь, чтобы написать комментарий!