|
Модераторы: Aliance, skyboy, MoLeX, ksnk |
|
Vardoulacha |
|
||||||||||
Бывалый Профиль Группа: Участник Сообщений: 183 Регистрация: 11.8.2005 Репутация: нет Всего: 8 |
Да, я умею разбивать строку на слова используя разделители пробелы, но... вот в чем вся соль
строка может быть такой, с ней проблем нет. т.к. всего три слова, два пробела, регулярка строится на раз два
но среди тех строк могут попадаться и вот такие
и даже такие
и вот тут уже встает проблема, если также делить пробелами то слов становится больше хотя на деле так и остается во всех строках всего 3 блока данных на ум приходит только одно решение, считать количество пробелов и используя это знание строить разные регулярки но этот метод ломается при вот таких строках: такой
и такой
может кто решал такие задачи, хоть направление бы дать а вот реальные данные Nokian 185/70 R14 92T HKPL5 Nokian 245/45 R18 100T HKPL 8 Run Flat XL Good Year 175/65 R14 82T UG ICE ARCTIC D-STUD Good Year 205/70 R15 96T UG ICE ARCTIC D-STUD SUV т.е. нужно парсить вот такие строки есть правда еще одна идея, парсить по спец знакам "/" "R" "T", затем по словам блоки бить и брать данные из блоков, т.е. если разбить на блоки получится в первом блоке Nokian 185 Good Year 205 таким образом последнее слово всегда будет понятно какое, а остальная часть там хоть одно слово хоть десять, уже неважно или может есть какой способ проще? |
||||||||||
|
|||||||||||
Aliance |
|
||||
I ♥ <script> Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 2 Всего: 137 |
Хорошо, что привели пример конкретной реализации. Конечно, в вашем случае нужно писать функцию с более-менее ручным алгоритмом. При чем желательно разбиваемые данные модерировать (проверять, что оин сформировались правильно), т.е. делать это не "на лету", а где-нибудь в фоне, сохранять в хранилище, а пользователю уже выводить из хранилища.
Как пример, сначала заводим массив брендов шин:
И далее пишем примерно следующую регулярку:
И дальше в регулярку пихать условия все по очереди. Добавлено через 14 секунд В итоге получилось что-то типа такого: http://ideone.com/LWXceo Если кидается ошибка - можно писать в лог и потом эту запись либо вручную, либо подправить регулярку. |
||||
|
|||||
Gold Dragon |
|
|||
Призрачный Профиль Группа: Экс. модератор Сообщений: 6753 Регистрация: 1.3.2004 Где: Россия, Тамбов Репутация: 1 Всего: 71 |
ничего не понял.
Покажи строку-оригинал и покажи что должно быть на выходе.. Я думаю так проще -------------------- Нельзя жить в прошлом, оно уже прошло. Нельзя жить в будущем, оно ещё не наступило. Нужно жить в настоящем, помня прошлое и думая о будущем! |
|||
|
||||
Vardoulacha |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 183 Регистрация: 11.8.2005 Репутация: нет Всего: 8 |
Aliance, мммм... класс. Да есть таблица с названиями брендов и названиями моделей, с этим как раз и была у меня сложность, а так да, путем поиска с использованием массива идея хорошая. Остальные данные можно будет уже потом выдрать другими регулярками, потому как порядок записи может быть разным. Пошел курить этот код. Я тоже склняюсь к тому что придется постоянно придумывать новые правила и отслеживать спотыкания скрипта, но другого выхода пока не вижу.
Брендов конечно немного, всего 262 )) А вот моделей 5566 )) Есть правда вот какая идея: после того как строка будет успешно разобрана помещать ее исходник (не разобранную строку) и ИД найденной шины в нашей базе шин в отдельную таблицу. И в будущем сначала эту строку искать в этой таблице. если такой нет тогда пробовать разобрать используя регулярки, и если это не прошло только тогда валить на почту ошибку чтобы дописали новое правило. Gold Dragon, а вот Aliance меня с первого раза понял )) строки на входе я привел. а на выходе должен получится массив разобранных данных. Это сообщение отредактировал(а) Vardoulacha - 21.11.2014, 12:07 |
|||
|
||||
Gold Dragon |
|
||||
Призрачный Профиль Группа: Экс. модератор Сообщений: 6753 Регистрация: 1.3.2004 Где: Россия, Тамбов Репутация: 1 Всего: 71 |
Я просто не понял что такое СЛОВО, а что такое СЛОВОСОЧЕТАНИЕ. И вопрос не в делении пробелами, а чем одно отличается от другого.. Вот и хотел увидеть что из этого
Добавлено через 2 минуты и 54 секунды ps кстати, сообщения писали в одно время я не видел ответ Aliance -------------------- Нельзя жить в прошлом, оно уже прошло. Нельзя жить в будущем, оно ещё не наступило. Нужно жить в настоящем, помня прошлое и думая о будущем! |
||||
|
|||||
baldina |
|
|||
Эксперт Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 4 Всего: 101 |
судя по примеру напрашивается классификация
<модель> <ширина/высота> <радиус> <нагрузка, скорость> <комментарий> это можно распарсить регуляркой, например
http://ideone.com/WdhKxv Это сообщение отредактировал(а) baldina - 21.11.2014, 14:34 |
|||
|
||||
Vardoulacha |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 183 Регистрация: 11.8.2005 Репутация: нет Всего: 8 |
Спасибо всем за помощь, остановился вот на такой строчке
Потом из последнего всего мусора выкидываю лишние спец слова (их немного) и получаю модель И вот отдав файл парсеру увидел что он запнулся на трех строках Michelin 235/60 R16 100Т LATITUDE X-ICE NORTH Michelin 235/60 R17 102Т X-ICE NORTH Michelin 295/35 R21 107Т X-ICE NORTH Обычные вроде строки. ничего сложного, но регулярка выдает пустой массив http://ideone.com/V20Sv7 При этом если эту же регулярку и эти же значения засунуть сюда http://www.regexr.com/ То там она парсится успешно, понятно что в онлайн не php, а js, но все остальные строки парсятся успешно, а эти вот нет, прям мистика (( |
|||
|
||||
baldina |
|
|||
Эксперт Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 4 Всего: 101 |
у вас в "100Т" T русская. добавьте модификатор 'u' или замените в регулярке \w на .
|
|||
|
||||
Vardoulacha |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 183 Регистрация: 11.8.2005 Репутация: нет Всего: 8 |
baldina, модификатор прокатил, спасибо большое.
|
|||
|
||||
Vardoulacha |
|
||||
Бывалый Профиль Группа: Участник Сообщений: 183 Регистрация: 11.8.2005 Репутация: нет Всего: 8 |
Добрый день, уважаемые, моя эпопея продолжается, те варианты что рассмотрели выше более неактуальны, вернее тогда казалось что это выход, но, на деле оказалось все гораздо сложнее.
Задача почти та же, только я регулярку сделал таким образом что понятные данные она выдирает правильно, а вот со словами надо как-то работать. Итак, предварительная обработка делает из этого
вот это
удалось написать несколько монстров которые выдирают цифры и оставляют только слова, и вот теперь самое интересное, как же узнать что среди этого бренд что модель а что доп параметры и к модели отношения не имеют Строка: Nokian HKPL5 Бренд: Nokian Модель: HKPL5 Параметры: Строка: Nokian HKPL 8 Run Flat XL Бренд: Nokian Модель: HKPL 8 Параметры: Run Flat XL так как программа дура, она визуально не может понять что где (привет Искусственный интеллект) я даже не прошу какое-то готовое решение, мне бы просто понять общий смысл как это выдрать ах да, есть идеальные базы где перечислены все бренды и все модели, пока придумалось такое решение: 1. Разбиваем строку по пробелам 2. Берем первое слово 3. Ищем среди брендов 4. Если ничего не найдено, значит или это действительно бренд и его нет в базе (но это можно в исключения потом кинуть и руками понять) либо бренд состоит из двух слов 5. Значит берем два слова и снова ищем в брендах (а может быть и 3 и 4 слова) 6. Если прогнав всю строку так и не нашли среди брендов, значит выкидываем строку, пусть программист сам визуально смотрит 7. Если бренд нашли. выкидываем его из начальной строки, сокращая ее и делаем все тоже самое с пункта 2 но уже для моделей 8. Когда найдем модель и выкинем ее из строки там останутся только параметры или пусто единственное ли это решение, или я мыслю однобоко??? UPDATE Только написал логику и тут же могу ее сломать, есть модель HKPL 8 и HKPL 8 SUV если будем искать логикой описанной выше, тогда получится следующее 1. Берем два слова HKPL 8 2. Ищем среди моделей и находим, не одну а несколько моделей 3. Значит теперь нам надо из найденных моделей выкинуть ту что искали, чтобы определить все возможные варианты следующего (или нескольких) слов 4. В примере найдем "" и " SUV" 5. Берем третье слово, если оно SUV значит надо брать вариант с SUV, иначе берем вариант без слова SUV и херак тут же и эту логику можно сломать, а если там слово TL (ну допустим), а у нас еще нет такой модели, тогда мы возьмем модель HKPL 8, что будет неверным, ведь оказывается есть новая модель HKPL 8 TL, но т.к. в системе нет такого значит это либо новая модель либо это параметр и он правильно отсеялся и модель HKPL 8, чорт ( Это сообщение отредактировал(а) Vardoulacha - 16.4.2015, 10:59 |
||||
|
|||||
Aliance |
|
|||
I ♥ <script> Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 2 Всего: 137 |
Vardoulacha, вы снова отдалились от решения, предложенного мною. Список брендов и их моделей конечный и легко может быть составлен, а значит и написать регулярку, проверяющуую какая у входной строки модель из заранее заготовленного списка, не составляет труда.
Добавлено через 3 минуты и 8 секунд
|
|||
|
||||
Vardoulacha |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 183 Регистрация: 11.8.2005 Репутация: нет Всего: 8 |
Aliance, да ваше решение хорошее, но есть одно но, если брендов довольно мало около 500, то моделей ОЧЕНЬ много база содержит уже более 3000 записей, и это только правильные названия моделей, а есть еще алиасы "кривых" названий (это когда вместо Yokohama написано например Yоkohama и только редакторы с подсветкой синтаксиса покажут в чем отличие этих двух строк, во втором слове первая буква "о" русская, даже не спрашивайте как эти криворукие смогли это написать, но это реальный пример). Еще в вашем решение есть один подвох, если бренды оно еще более менее проработает, то вот с такими моделями уже не прокатит: Nokian 275\75 R16 HKPL 8 98T SUV, пример выдуманный (сейчас нет под рукой реального) , но смысл думаю понятен, модель HKPL 8 SUV разбита на две части.
Передумал я еще множество различных вариантов и остановился вот на таком: 1. Берем SQLite 2. Собираем таблицы с помощью команды CREATE VIRTUAL TABLE TableName USING FTS4 http://www.dotnetperls.com/sqlite-fts3 3. Создаются таблицы со всеми записями типа Бренд1 Модель1, Бренд1 МодельАлиас1, Бренд1 МодельАлиас2 Файл с базой получился на 570 мегабайт Далее выдираем из строки размеры шины (это в принципе сделать легко получилось т.к. там хоть логика есть), а все что остается кроме размеров это бренд и модель которые становятся одной строкой, далее используем запрос в таблицу SELECT data FROM BrandModel WHERE alias MATCH string Работает ооочень быстро, а также данное решение легко расширяется без участия программиста, надо просто дополнять базу кривыми алиасами, чтобы строка успешно распознавалась. Мне кажется это лучшее решение )) Пока нашли тут только один минус, это размер базы данных, но согласно спецификации SQLite Количество таблиц в БД = 2 147 483 646 (у меня всего то 4 таблицы) Размер БД = 140 терабайт !!! так что тут скорее лимит в размер файла в файловой системе, не помню точно какая файловая система на сервер и какой размер блока, но даже если это ext3 и размер блока 1 кб то это максималка 16 гигабайт, что тоже кажется слишком избыточным
|
|||
|
||||
Aliance |
|
|||
I ♥ <script> Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 2 Всего: 137 |
А кривые алиасы поступают вам на вход или хранятся в вашей базе? Если второе - то не проще ли написать скрипт, который заменяет кривизну в моделях и периодически его запускать?
|
|||
|
||||
Vardoulacha |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 183 Регистрация: 11.8.2005 Репутация: нет Всего: 8 |
В том то и соль, что кривые алиасы поступают извне и заранее неизвестны.
База sqlite разрослась до 3.8 гб )) Посматриваем в сторону MongoDB |
|||
|
||||
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | PHP: Тексты | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |