Модераторы: ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не учитывать совпадение при определенных условиях, нежелательные символы 
:(
    Опции темы
Akella
  Дата 25.5.2012, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



Есть выражение для поиска номеров телефонов:
Код
(\d[\d-•() ]{6,17})|(/\d{3,3}/[\d-•() ]{6,17})


но в тексте часто встречается не только номер телефона, но и цена, или какой-нибудь номер, например, номер объявления
Цитата
м Голосеевская 3-7 мин., 64423457, дата: 25.05.2012

Цитата
тип: Монолитный, цена 154500 у.е. продам


Вопрос. Как построить выражение, которое будет пропускать такие вот совпадения, если в совпавшем тексте найден нежелательный(е) символ(ы)?
PM MAIL   Вверх
Pfailed
Дата 25.5.2012, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 6
Всего: 39





--------------------
PM MAIL   Вверх
Akella
Дата 25.5.2012, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



не доходит, а можно конкретнее?
PM MAIL   Вверх
Pfailed
Дата 25.5.2012, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 6
Всего: 39



Например здесь мы ищем цифры. Но если перед цифрами знак номера, то такие цифры нам не подходят.
На выходе вторая match группа содержит 1234.
Код

'abc № 4444444 fff 1234' =~ /(?:(№\s*)|\b)(\d+)(*SKIP)(?(1)(*FAIL))/ or die;


Словами это выражение: 
(
  1-я альтернатива - найти знак номера, затем возможно пробелы
  2-я альтернатива просто разделитель отделяющий цифры
)
затем цифры, которые мы ищем
просим движок рег выражений не возвращаться на позицию до текущей если поиск потерпит неудачу
говорим что поиск неудачен если найдена 1-я альтернатива

Таким образом:
движок находит "№ 4444444" - 1-я альтернатива
получает указание что поиск неудачен - FAIL
возвратиться за 4444444 он уже не может - SKIP
ищет далее и находит уже 2-ю альтернативу "1234" (действительно тут нет знака номера)
2-я альтернатива - это не первая -> поиск успешен

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



--------------------
PM MAIL   Вверх
alezzz
Дата 25.5.2012, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


сплю...
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 17.8.2009

Репутация: 11
Всего: 14



а возле номера телефона есть за что зацепться, например "тел." или код города в скобках?
не в тему, недочитал и непонял суть вопроса.

Это сообщение отредактировал(а) alezzz - 25.5.2012, 23:30
PM MAIL   Вверх
Akella
Дата 26.5.2012, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



Цитата(alezzz @  25.5.2012,  20:48 Найти цитируемый пост)
а возле номера телефона есть за что зацепться, например "тел." или код города в скобках?


к сожалению часто бывает так, что нет никаких других признаков, того же признака тел не бывает иной раз :(
PM MAIL   Вверх
Akella
Дата 26.5.2012, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



а как насчет просмотра вперед или назад
http://ru2.php.net/manual/ru/regexp.reference.assertions.php

(?<=bullock|donkey)
PM MAIL   Вверх
Pfailed
Дата 26.5.2012, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 6
Всего: 39



Просмотр вперед годится, но просмотр назад в Perl должен быть фиксированой длинны, т.е никаких "*" или "+". Хотя в некоторых других языках, .Net например, такого ограничения нет.


--------------------
PM MAIL   Вверх
Akella
Дата 21.6.2012, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



Не понял, что не так.
Вот выражение
Код
(?!№)\d[\d-•() ]{6,17}|(?!№)/\d{3,3}/[\d-•() ]{6,17}


Вот текст:
Цитата
Смирнова-Ласточкина, . ТЛФ: +380-67-8763116,  цена: 7 000 грн.,  (067)8763116P.S. Возможна сдачи квартиры под EURO-2012 Call., №68651705, дата: 20.06.2012


Выражение находит все три группы цифр, в том числе и 68651705, хотя это нужно пропускать

Что не так в этом выражении?
PM MAIL   Вверх
DurRandir
Дата 21.6.2012, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 335
Регистрация: 27.9.2009

Репутация: 2
Всего: 17



Много почему))

1. Потому что ?! - это look-ahead assertion. А look-behind - это ?<!
2. Заменили, отлично. Но теперь матчинг для выражения №1234567 будет начинаться не с позиции №-->1<--2345, а с позиции №1-->2<--345, т.е. просто пропускает 1ю цифру. Поэтому добавим ещё одно условие - ?<!\d

Итого, получается что-то вроде (+я свернул общий хвост у выражений)
Код

 (?<!№)(?<!\d)(?:\d|\/\d{3,3}\/)[\d-() ]{6,17}


Это сообщение отредактировал(а) DurRandir - 21.6.2012, 16:06
PM   Вверх
Akella
Дата 21.6.2012, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



Цитата(DurRandir @  21.6.2012,  16:05 Найти цитируемый пост)
(?<!№)(?<!\d)(?:\d|\/\d{3,3}\/)[\d-() ]{6,17}


всё равно находит
PM MAIL   Вверх
DurRandir
Дата 21.6.2012, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 335
Регистрация: 27.9.2009

Репутация: 2
Всего: 17



Код

print "$_\n" for ('abc: +380-67-8763116, fsdfds, (067)8763116P.S. EURO-2012 Call., #68651705, dare 20.06.2012' =~ /(?<!#)(?<!\d)(?:\d|\/\d{3,3}\/)[\d-() ]{6,17}/g);

380-67-8763116
067)8763116

Я проверял на приведённой строке. Если какие-то другие данные - покажите.

Это сообщение отредактировал(а) DurRandir - 21.6.2012, 18:11
PM   Вверх
Akella
Дата 22.6.2012, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



Цитата(DurRandir @  21.6.2012,  18:11 Найти цитируемый пост)
#68651705


у меня №, а не #

Добавлено через 48 секунд
Цитата(DurRandir @  21.6.2012,  16:05 Найти цитируемый пост)
Но теперь матчинг для выражения №1234567 будет начинаться не с позиции №-->1<--2345, а с позиции №1-->2<--345, т.е. просто пропускает 1ю цифру.

да, это я уже ещё вчера понял :(
PM MAIL   Вверх
Akella
Дата 22.6.2012, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: нет
Всего: 329



Цитата(DurRandir @  21.6.2012,  18:11 Найти цитируемый пост)
print "$_\n" for ('abc: +380-67-8763116, fsdfds, (067)8763116P.S. EURO-2012 Call., #68651705, dare 20.06.2012' =~ /(?<!#)(?<!\d)(?:\d|\/\d{3,3}\/)[\d-() ]{6,17}/g);


Что-то у Вас тут напутано со скобками, как мне кажется

Добавлено через 1 минуту и 45 секунд
Вот это выражение вообще ничего ненаходит:
Код
(?<!#)(?<!\d)(?:\d|\/\d{3,3}\/)[\d-() ]{6,17}/g


Добавлено через 2 минуты и 25 секунд
а вот это работает: 
Код

(?<!#)(?<!\d)(?:\d|\/\d{3,3}\/)[\d-() ]{6,17}


Добавлено через 3 минуты и 35 секунд
Но всё равно находит: 

user posted image

Добавлено через 3 минуты и 47 секунд
Может дело в знаке ?

Добавлено через 4 минуты и 38 секунд
Да, действительно, если изменить в тексте объявления № на # и в выражении, то всё ок
PM MAIL   Вверх
DurRandir
Дата 22.6.2012, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 335
Регистрация: 27.9.2009

Репутация: 2
Всего: 17



>Вот это выражение вообще ничего ненаходит
А вы не в перле смотрите, судя по скриншоту. Там концовка - /g - модификатор поиска всех совпадений, и требует стартового слеша / - они играют роль скобок-ограничителей.

>всё равно находит
Возможно, проблема в юникоде/кодировках? Я потому и проверял на ASCII-строке, чтобы это не влияло.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Регулярные выражения | Следующая тема »


 




[ Время генерации скрипта: 0.1579 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.