|
Модераторы: ginnie |
|
Akella |
|
||||||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Есть выражение для поиска номеров телефонов:
но в тексте часто встречается не только номер телефона, но и цена, или какой-нибудь номер, например, номер объявления
Вопрос. Как построить выражение, которое будет пропускать такие вот совпадения, если в совпавшем тексте найден нежелательный(е) символ(ы)? |
||||||
|
|||||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
Например так: http://forum.vingrad.ru/index.php?showtopi...t&p=2413918
|
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
не доходит, а можно конкретнее?
|
|||
|
||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
Например здесь мы ищем цифры. Но если перед цифрами знак номера, то такие цифры нам не подходят.
На выходе вторая match группа содержит 1234.
Словами это выражение: ( 1-я альтернатива - найти знак номера, затем возможно пробелы 2-я альтернатива просто разделитель отделяющий цифры ) затем цифры, которые мы ищем просим движок рег выражений не возвращаться на позицию до текущей если поиск потерпит неудачу говорим что поиск неудачен если найдена 1-я альтернатива Таким образом: движок находит "№ 4444444" - 1-я альтернатива получает указание что поиск неудачен - FAIL возвратиться за 4444444 он уже не может - SKIP ищет далее и находит уже 2-ю альтернативу "1234" (действительно тут нет знака номера) 2-я альтернатива - это не первая -> поиск успешен Используя такую технику можно создавать достаточно сложные условия для выражений, которые не должны встречаться. |
|||
|
||||
alezzz |
|
|||
сплю... Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 11 Всего: 14 |
а возле номера телефона есть за что зацепться, например "тел." или код города в скобках?
не в тему, недочитал и непонял суть вопроса. Это сообщение отредактировал(а) alezzz - 25.5.2012, 23:30 |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
||||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
а как насчет просмотра вперед или назад
http://ru2.php.net/manual/ru/regexp.reference.assertions.php (?<=bullock|donkey) |
|||
|
||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
Просмотр вперед годится, но просмотр назад в Perl должен быть фиксированой длинны, т.е никаких "*" или "+". Хотя в некоторых других языках, .Net например, такого ограничения нет.
|
|||
|
||||
Akella |
|
||||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Не понял, что не так.
Вот выражение
Вот текст:
Выражение находит все три группы цифр, в том числе и 68651705, хотя это нужно пропускать Что не так в этом выражении? |
||||
|
|||||
DurRandir |
|
|||
Опытный Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 2 Всего: 17 |
Много почему))
1. Потому что ?! - это look-ahead assertion. А look-behind - это ?<! 2. Заменили, отлично. Но теперь матчинг для выражения №1234567 будет начинаться не с позиции №-->1<--2345, а с позиции №1-->2<--345, т.е. просто пропускает 1ю цифру. Поэтому добавим ещё одно условие - ?<!\d Итого, получается что-то вроде (+я свернул общий хвост у выражений)
Это сообщение отредактировал(а) DurRandir - 21.6.2012, 16:06 |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
||||
|
||||
DurRandir |
|
|||
Опытный Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 2 Всего: 17 |
Я проверял на приведённой строке. Если какие-то другие данные - покажите. Это сообщение отредактировал(а) DurRandir - 21.6.2012, 18:11 |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
||||
|
||||
Akella |
|
||||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Что-то у Вас тут напутано со скобками, как мне кажется Добавлено через 1 минуту и 45 секунд Вот это выражение вообще ничего ненаходит:
Добавлено через 2 минуты и 25 секунд а вот это работает:
Добавлено через 3 минуты и 35 секунд Но всё равно находит: Добавлено через 3 минуты и 47 секунд Может дело в знаке №? Добавлено через 4 минуты и 38 секунд Да, действительно, если изменить в тексте объявления № на # и в выражении, то всё ок |
||||
|
|||||
DurRandir |
|
|||
Опытный Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 2 Всего: 17 |
>Вот это выражение вообще ничего ненаходит
А вы не в перле смотрите, судя по скриншоту. Там концовка - /g - модификатор поиска всех совпадений, и требует стартового слеша / - они играют роль скобок-ограничителей. >всё равно находит Возможно, проблема в юникоде/кодировках? Я потому и проверял на ASCII-строке, чтобы это не влияло. |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
ну да, наверное, у буржуев ведь нет знака №
Добавлено через 11 секунд и программа не юникодная Добавлено через 39 секунд в общем я перешёл на #, пока что |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Хочу поднять тему, т.к. есть ещё проблема.
В тексте объявлений есть телефоны. А также есть вот такой текст: решения соответствуют требованиями СНиП 31-01-2003 Здания Получается так, что выделенная группа цифр определяется, как номер телефона. Можно что-то придумать такое, что если перед номером есть слово: "СНиП ", то игнорировать найденный текст? |
|||
|
||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
Как была решена предыдущая проблема?
Это сообщение отредактировал(а) Pfailed - 12.4.2013, 15:51 |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
||||
|
||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
На мой взгляд некорректное выражение. Удовлетворяет строке: решения соответствуют требованиями #01-01-2003 Здания.
А должно ли? Это сообщение отредактировал(а) Pfailed - 12.4.2013, 17:28 |
|||
|
||||
DurRandir |
|
||||
Опытный Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 2 Всего: 17 |
Я бы чуть по другому сделал. Т.к. перед датой может не только "СНИП" идти (и придётся составлять список слов-исключений - регулярка расползётся быстро), я бы вырезал \d{2}-\d{2}-\d{4} как невалидный формат (никто так телефон не делит). Т.е. либо задал для хвоста [\d-() ]{6,17} более строгий формат, либо добавил соответствующий assertion: (?!\d{2,2}-\d{2,2}-\d{4,4}). Итого:
*добавление* а оно же начнёт матчиться после -01-2003 В общем, лучше уточнить валидный формат или делать доп. проверку *после* поиска и выкидывать такие совпадения. Т.к. я не уверен, что даже нечто в духе
не зацепит лишнего Это сообщение отредактировал(а) DurRandir - 12.4.2013, 18:22 |
||||
|
|||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
А в чём фишка писать \d{n,n}? Разве это не эквивалентно \d{n}?
Добавлено через 6 минут и 10 секунд Но и не отработает на валидной (по условию) строке: решения соответствуют требованиями -01-01-2003 Здания |
|||
|
||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
Вариация на тему моего первого поста в этой теме
Уже в коде смотрим на вторую match группу. Если она определена -- берем ее значение. Если не определена -- переходим на следующую итерацию. Это сообщение отредактировал(а) Pfailed - 12.4.2013, 18:44 |
|||
|
||||
DurRandir |
|
||||
Опытный Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 2 Всего: 17 |
Да я не везде исправил. Эквивалентно)
"Если у вас есть проблема, и вы собираетесь решать ее с использованием регулярных выражений, то у вас есть две проблемы" в полный рост, в общем то) Можно только гадать, подойдёт или не подойдёт под реальные данные, которые есть у Akella. Это сообщение отредактировал(а) DurRandir - 12.4.2013, 18:42 |
||||
|
|||||
Akella |
|
||||||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
Не то. а НЕ должно находить Добавлено через 9 минут и 49 секунд
а вот это уже норм Добавлено через 10 минут и 8 секунд Можно его словесно расшифровать? |
||||||
|
|||||||
Pfailed |
|
|||
Опытный Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 6 Всего: 39 |
В какой match группе нашлось? Я же написал вам, что нужно смотреть только на вторую match группу. Все исключения в первую match группу, все подходящие во вторую. |
|||
|
||||
DurRandir |
|
|||
Опытный Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 2 Всего: 17 |
Я в том посте постарался описать, как конструировать. Оно состоит из 3х частей - двух отрицательных якорей: (?<!) - не начинать матчинг, если до позиции стоит -#\d (?!) - если строка дальше попадает под формат d{2}-\d{2}-\d{4}, то так же не начинать матчинг и потом положительная проверка под подходящий формат |
|||
|
||||
Akella |
|
|||
Творец Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: нет Всего: 329 |
К сожалению, "смотреть" только туда или только сюда - не подходит, потому что в одном случае будет это выражение, а в другом случае будет другое выражение, но программа одна на всех, как говорится. Можно менять только образец (выражение поиска). |
|||
|
||||
tishaishii |
|
|||
Создатель Профиль Группа: Завсегдатай Сообщений: 1262 Регистрация: 14.2.2006 Где: Москва Репутация: нет Всего: 8 |
Создавал такое рег.выр. импирически около 3х лет. Задача была вынимать объявления из отсканированных и распознанных объявлений, преобразованных в HTML. И нужно было искать номера телефонов в БД, чтобы показывать, обработан ли податчик объявления.
В общем, импирически, рег.выр. хранился в отдельном файле около 2х кб + дополнительный анализ подстрок. |
|||
|
||||
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Perl: Регулярные выражения | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |