| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Форум группы: delphi > Примеры регулярных выражений |
| Автор: Akella 13.5.2009, 08:53 | ||||
| С этого сайта http://regexpstudio.com/ скачал библиотеку и exe`шник (RegExpr Test Program). Задача такая. Есть текст:
нужно из текста выцепить тип объекта недвижимости. Для этого нужно выцепить из текста конкретные слова. В данном случае: КВАРТИРА, Квартира, КВ, Кв. (1 строка = 1 одъявлений) Запускаю RegExpr Test Program (v.0947), копирую туда текст объявления, ввожу выражение:
И ещё, модификаторы нужно вводить так? (выражение)(ims) или по другому? |
| Автор: Akella 13.5.2009, 14:48 | ||
пока составил такую регулярку
|
| Автор: Akella 13.5.2009, 15:15 | ||
| не могу допереть, как работать с окончаниями. Есть в тексте 2 слова, которые нужно выцепить ИЗОЛИРОВАННАЯ и ИЗОЛИРОВАННУЮ эта регулярка: изолированн[ау] ловит ИЗОЛИРОВАННА или ИЗОЛИРОВАННУ а как полностью слова найти? Добавлено через 4 минуты и 49 секунд ураа
|
| Автор: cemick 13.5.2009, 16:00 |
| ?((\d)(-)К\.КВ|К\.|КВАРТИРА) Добавлено через 1 минуту и 18 секунд ой, куда то пост исчез, в котором спрашивалось как вытащить квартиру... |
| Автор: Akella 13.5.2009, 16:36 |
| Всё, я допёр, что перед точкой нужно ставить слеш \ Добавлено через 1 минуту и 26 секунд зачем вопросительный знак? Добавлено через 4 минуты и 15 секунд количество комнат в отдельном месте нуна узнавать Просто из текста объявления нужно выцепить как можно больше интересной и нужной информации, как то: тип недвижимости, район, улицу, цену, телефоны, комнат, этажность, площади. Т.е. разбить объявление на части, шоб потом запихнуть всё красиво и аккуратно в базу. Пока потихоньку продвигаюсь. |
| Автор: cemick 13.5.2009, 17:04 |
случайно там оказался |
| Автор: Akella 14.5.2009, 17:08 | ||
Красным выделены площади (общая, жилая, кухни), как будет выглядеть регулярка? Хотелось бы выцепить три группы цифр, разделённых слешем: 20/10,5/7 такое: 11/14 или такое: 1/9 нужно пропускать |
| Автор: Akella 15.5.2009, 09:08 | ||
Теперь задача усложнилась. Требуется найти только такое: 1/5 или 11/14, т.е. этажность, этаж/этажность дома
Зелёным выделено то, что нужно найти, красным выделено то, что брать во внимание не требеутся. |
| Автор: cemick 15.5.2009, 09:22 |
| \s(\d*/\d*),\s |
| Автор: Akella 15.5.2009, 10:41 |
| cemick, супер! |
| Автор: Akella 17.5.2009, 20:52 | ||
Тут выявилась проблема с поиском слов вначале предложения.
но если в тексте появляются слова, которые содержат в себе слово дом, например, домовитый, домашний, издому, то такие слова нужно пропускать Вот регулярка: (?ir)(уч-к|коттедж|([^а-Я]| )дом([^а-Я]| )|домик[^а-Я]|часть дома|полдома|пол дома|усадьб(а|у)|дач(а|у)|земля|зем. участок|зем.участок|земельный участок|участок зем.|участок земли|участок |ПОД ЗАСТРОЙКУ |ПОД ЗАСТРОЙКУ\.) Эта регулярка не видит слово ДОМ вначале предложения. |
| Автор: cemick 18.5.2009, 10:20 |
| Не видит потому, что ([^а-Я]| ) предполагает наличие хотя бы одного символа.. (?ir)(уч-к|коттедж|^([а-Я])*дом([а-Я])*|домик[^а-Я]|часть дома|полдома|пол дома|усадьб(а|у)|дач(а|у)|земля|зем. участок|зем.участок|земельный участок|участок зем.|участок земли|участок |ПОД ЗАСТРОЙКУ |ПОД ЗАСТРОЙКУ\.) |
| Автор: Akella 18.5.2009, 10:36 |
| А как "сказать" парсеру, что если в тексте встречается какое-нибудь слово или выражение, то не обрабатывать такой текст вообще? Допустим есть текст. В нём мы ищем слово дом. Но если в тексте есть слово квартира, то не нужно обрабатывать такой текст. |
| Автор: cemick 18.5.2009, 13:03 |
| скорее всего ни как |
| Автор: Akella 18.5.2009, 13:26 | ||
Тогда такой вопрос.
регулярка (?ir)((^м\.кв)|[^а-Я\ ]кв[^а-Я]|кв,|изолированн(ая|ую)|гостинк(а|у)|комнат(у|а|ы)|из\. кв\.|из\.кв\.|из\.кв,|ГОСТ\.|комн. из|комн.из) думает, что это квартира из-за выделенного красным цветом. Как указать, что бы на м кв м. кв м. кв. кв. м. кв м кв. м кв м. парсер не обращал внимание? |
| Автор: cemick 18.5.2009, 14:11 |
| Тут наверно надо более точно задавать условие поиска квартир, например, мы знаем что перед "кв" не может быть чисел: [,;\A]{1}[\s\D]*кв[^а-Я] (сочетание букв "кв" до которых может быть куча пробельных символов и один терминальный, либо начало строки) вместо регулярного выражения: [^а-Я\ ]кв[^а-Я] для предложения ДОМ, Автовокзал, 2К, 50кв. м., хор.сост., газ, лет.кухня, вода во дворе |
| Автор: Akella 18.5.2009, 15:31 | ||
За то теперь такое:
не может определить |
| Автор: Akella 18.5.2009, 15:48 | ||
(?ir)(уч-к|коттедж|^([а-Я])*дом([а-Я])*|домик[^а-Я]|часть дома|полдома|пол дома|усадьб(а|у)|дач(а|у)|земля|зем. участок|зем.участок|земельный участок|участок зем.|участок земли|участок |ПОД ЗАСТРОЙКУ |ПОД ЗАСТРОЙКУ\.) Нудно было убрать то, что красным |
| Автор: cemick 18.5.2009, 15:52 |
почему? ^ -- ??? В смысле убрать, это обозначает начало строки? |
| Автор: Akella 18.5.2009, 16:02 |
| Ну не знаю, вот щас так определяет: Дом, 60 м2, газ, удобства, телефон, Люботин, экв. 26 т.д. Дом, 85 м*2, Хол. Гора, Лен. сторона, тел., вода, 6 сот., уч. ровн., 50 т.у.е. Дом Дом, Дом все 5 слов Дом |
| Автор: Akella 18.5.2009, 16:33 |
| Не могу найти в справке, как указать отрицание, несоотетствие. Допустим предложение Дом ХТЗ Фрунзе флигель Зкомнаты, жилое состояние, вода во дворе, газ, канализация по улице, гараж, 3 сотки регулярка: ((?ir)(\d(к|-к[^у]| из|из|/из| к\.| -к| к[ом]){1,6})|Зиз|Зк.) определяем, что это квартира из-за выделенного красным Как бы указать что-то вроде: ((?ir)(\d(к|-к[НЕу]| из|из|/из| к\.| -к| к[ом][НЕомнаты]){1,6})|Зиз|Зк.) Добавлено через 4 минуты и 14 секунд там вообще буква "З" |
| Автор: Akella 18.5.2009, 16:48 | ||
| Вот хороший пример Полдома в Люботине, 2 комнаты, большая кухня, Вот регулярка: ((?ir)(\d(к |-к[^у]| из|из|/из| к\.| -к| к[ом]){1,6})|Зиз|Зк\.) Из-за выделенного красным парсер думает, что это квартира, скорее всего из-за этого: к[о (выделено зелёным) Но вот это уже должно захавать, т.е. это изолированная квартира В Люботине, 2 комн. из. кв. , большая кухня, отапливаемая веранда, газ, вода, Что тут придумать? Добавлено через 6 минут и 26 секунд
смотря в каком месте этот символ ^ Добавлено через 8 минут и 35 секунд Пока придумал так: ((?ir)(\d(к |-к[^у]| из|из|/из| к\.| -к| к(ом\.|омн\.|[^ комнаты])){1,6})|Зиз|Зк\.) потом посмтотрим |
| Автор: Akella 18.5.2009, 19:37 | ||||
вот так часто начинаются объявления: 3-к. из.кв. 3-к. из. кв. 3-комн. из.кв. 3-ком. из. кв. 3-к. приват. кв. Добавлено через 1 минуту и 7 секунд
а если [^(комнаты)] |
| Автор: cemick 18.5.2009, 20:18 | ||
Дак тут же дефис еще стоит, который можно учитывать для исключения ложных срабатываний Добавлено через 1 минуту и 17 секунд Так вроде не позволяет синтаксис регулярных выражений |
| Автор: Akella 18.5.2009, 20:20 | ||
Ну вместо дефиса может быть проблел или ничего не может быть:
|
| Автор: Akella 19.5.2009, 09:08 |
| Как сказать парсеру, что, например, слово: рядом не должно браться во внимание |
| Автор: Akella 19.5.2009, 17:06 | ||||
| cemick, тут в твоём примере небольшой казус: вот твоя регулярка: (?ir)([,;\A][\s\D]{1}*кв[^а-Я]|изолированн(ая|ую)|гостинк(а|у)|комнат(у|а|ы)|из\. *кв\.|из\.*кв,|ГОСТ\.|комн. *из|комн. пр. *кв|З *из. *кв|3 из\? *кв.|3 *из. *кв) Красным выделено то, что ты недавно посоветовал использовать, чтобы пропускать в тексте квадратные метры, например
да, всё правильно, зелёный текст во внимание не берётся, теперь немного дёгтя вот текст, это всё квартиры, видно это по тому, что вначале текста 2-к. кв. 2-ком. кв. 5-к. кв.
но из-за выделенного красным куска регулярки... такие объявления не учитываются, а должны, что ещё можно придумать :( |
| Автор: cemick 20.5.2009, 09:00 |
| Ну смотря что надо Можно и просто добавить учет еще и точки |
| Автор: Akella 20.5.2009, 10:01 |
надо и так и так, спасибо, глянем |
| Автор: Akella 20.5.2009, 22:21 |
| Усложняем задачу. Есть таблица. В таблице есть поле текстовое, в котором хранятся названия районов города. Типа, вокзал, центр, ленинский, комсомольский, московский. Так вот... как бы наиболее оптимально узнать из текста название района? Вообще, стоит ли прибегать к помощи регулярок. Может динамически построить регулярку вида: (район1|район2|район3|район4|район5|районN) Ну в небольших городах мало районов. Но... может быть, например, около 500, а то и все 1500 районов. Что посоветуете? Я пока склоняюсь к построению динамической регулярки. |
| Автор: cemick 21.5.2009, 09:48 |
| Наверно динамически, районов все таки сильно ограниченное количество и это будет самый надежный способ. |
| Автор: Akella 21.5.2009, 10:36 |
| В доке не нашёл, автор молчит, как рыба об лёд. Может кто знает ограничение на длину регулярки, если таковое имеется? |
| Автор: CodeMonkey 21.5.2009, 12:21 |
| Я может не в тему влезу, но может быть http://blogs.msdn.com/oldnewthing/archive/2006/05/22/603788.aspx и написать проверку вручную? Ничего особо сложного тут нет - быстрее руками сделать, чем подбирать рег. выр. Наверное, оптимально будет использовать рег. выр. для проверок частей и общую логику для всего выражения. |
| Автор: Akella 21.5.2009, 12:32 |
| CodeMonkey, не понял, покажи на пример, если не тяжело |
| Автор: Akella 21.5.2009, 12:49 | ||
| Хуже всего, что в названиях районов могут встречаться служебные символы, как минимум точка. StringReplace, конечно же спасёт гиганта мысли, но от пользователя Добавлено @ 12:58 Нет. строить регулярку из сотни районов не годится. Произвдительности вообще нет. Программа, можно сказать, не работает. Добавлено через 12 минут и 2 секунды
как вам регулярка |
| Автор: CodeMonkey 21.5.2009, 13:46 |
| Акелла, я про то, что не удасться уложить эти правила в рег. выражение. А даже, если удасться, то решение будет настолько страшным, что его нельзя будет ни модифицировать, ни отлаживать. Этакий write-only language. Лучше сделать это обычным кодом. Ну что-то типа синтаксического анализатора. Разбить строку на части (зяпятые?), попытаться выяснить смысл каждой части. Да, он может зависеть от смысла предыдущих/последующих частей, но тем не менее это можно сделать. Сами рег. выр. можно использовать при разбиении на части или при анализе каких-то частей. |
| Автор: Akella 21.5.2009, 14:14 |
я нашёл ашипку |
| Автор: cemick 21.5.2009, 16:29 | ||
все правильно, товарищ из блога решил выполнить с помощью регулярных выражений то, что уже относится семантическому анализу, к чему они не приспособлены. В результате он сделал правильно, фактически совместил регулярное выражение ((\d{3}).(\d{3}).(\d{3}).(\d{3})) выполняющее синтаксический анализ входной строки, и семантический анализ полученных токенов. |
| Автор: Akella 21.5.2009, 16:45 |
| http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%90%D1%85%D0%BE_%E2%80%94_%D0%9A%D0%BE%D1%80%D0%B0%D1%81%D0%B8%D0%BA |
| Автор: cemick 21.5.2009, 17:18 |
RegExpr его реализует?? Ну чисто субъективно он работает быстрее, чем если бы в ручную выполнять линейный поиск |
| Автор: Akella 21.5.2009, 17:44 |
Без понятия. Этот алгоритм мне подсказали на sql.ru |
| Автор: Akella 27.5.2009, 13:36 | ||
Сейчас пытаюсь наиболее правильно и оптимально находить цену. К сожалению цена и телефон могут быть схожи.
Цены выделил красным. Может перед парсингом преобразовывать тыс. долл., т.д. к нулям? Добавлено @ 13:49 Для начала. (?ir)(экв\. *\d{1,}( *тыс\.)|экв\. *\d{1,}( *т\.)) |
| Автор: FireIce 12.10.2009, 10:35 |
| Кто мне подскажет как работает функция frac? |
| Автор: Akella 12.10.2009, 22:41 |
| FireIce, frac - это из регулярок что-то?? |
| Автор: Akella 20.10.2009, 11:47 | ||
Есть строка
на сайте это выглядит так: ![]() Нужно вычислить адрес следующей страницы, в цитате выделено красным. Т.к. подстрок очень похожих может быть несколько, то такая регулярка (?i)(</a> <a href=".*?>Следующая) даёт неверный результат. Заставить DiRegEx искать с конца строки с помощью символа - $ так и не смог. Что посоветуете? Добавлено через 5 минут и 35 секунд Добавлю, что текст, выделенный красным, может быть и другой. Зависит от рубрики каталога, например вот: /cars/passenger/used/page2/ |
| Автор: evorios 22.10.2009, 16:37 |
| твоё первое сообщение по теме 13.5.2009, не уж то ещё не разобрался? "([^"]+)" class="nxt-page more"><span>следующая |
| Автор: Akella 22.10.2009, 18:23 |
| evorios, не помню, наверное разобрался же. С посленим тоже разобрался. Парсил в два этапа. |
| Автор: Akella 12.7.2010, 11:04 | ||
| Требуется найти ссылку на следующую страницу на сайте. Т.е. на сайтах с объявлениями, как правило внизу или вверху список страниц есть. Вот мне нужно пройтись по всем. Красным я выделил то, что нужно искать.
Из-за того, что на сайте есть ещё и поиск (параметры поиска), то ссылки на след. страницу могут выглядеть немного по-разному, т.е. в ссылку ещё и параметры попадают. Но в конце есть параметр p=1, который означает номер страницы, начиная с нуля. /catalog/13?r=10501&s=1&t=1&o=0&p=1 /catalog/13?r=10501&s=1&t=1&o=0&p=2 /catalog/13?q=&t=1&s=1&buy=0&o=0&r=10000&r1=10500&cur=0&pf=0&pt=0&p=5 Т.о. мне нужно получить всю ссылку, а не только последний параметр. Основная проблема в том, что в этом блоке есть куча похожих ссылок. Добавлено через 7 минут и 24 секунды У меня получается 2 выражения: (?i)предыдущая(.*?)следующая и (?i)"(.*?)" Т.е. сначала получаю: предыдущая</span> <a href="/catalog/13?r=10501&s=1&t=3&o=0&p=1" id="nextLink" title="Ctrl + стрелка вправо">следующая а потом из полученного уже получаю, то что нужно: /catalog/13?r=10501&s=1&t=3&o=0&p=1 А можно как-то выдрать одним выражением? Исп. DIRegeEx |