Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Регулярные выражения > Регулярные выражения


Автор: Anark1 27.7.2009, 19:24
Приветствую.
Не так давно начал изучать Perl.
Возник вопрос насчет выделения из строки, фрагмента, в котором отсутствует заданная подстрока.
Например, выделить из строки "<ABCD>EFG>" фрагмент "<ABCD>" следующим образом : от символа "<" до ">" с отсутствием "EFG".
Я использую
Код

s/<.*(EFG){0}>//;

этот код не работает (выделяет всю строку).
Я, очевидно, неправильно пытаюсь указать интерпретатору, что "EFG" отсутствует.
Прошу не закидывать тухлыми помидорами и не отправлять в поиск. Задача вроде бы для знающих не очень сложная.
Заранее спасибо.

Автор: Itsys 27.7.2009, 19:35
что значит "выделить"?

Если просто от символа < до символа >:
Код

s/\<([^\>]+)\>//

Автор: Logo 27.7.2009, 19:38
Насколько понял задачу, нужно
Код

/<(?:(?!EFG).)*>/

Автор: ginnie 27.7.2009, 19:44
Anark1, я сделал так

Код

my $test = "<ABCD>EF>";
print($test =~ /(.*)EFG/ ? $1 : $test);

Автор: Anark1 27.7.2009, 19:47
Itsys, не просто от и до. Думаю, ваш код также будет работать на примере, но мне нужен случай именно с отсутствием некоторой подстроки.


Logo, спасибо, не поясните немного? И заодно если не сложно, почему не работает мой вариант с квантификатором?

Автор: ginnie 27.7.2009, 19:53
Anark1, Ваше выражение удаляет в строке все символы начиная с < и до конца строки.

Автор: Anark1 27.7.2009, 20:08
ginnie, да это я знаю smile меня интересует "почему".
Ладно, вопрос решен, всем спасибо.

Автор: Logo 27.7.2009, 22:06
Потому что там так напсано  smile вернее от < и до (EFG), совпадающего ноль раз, за которым идет >. Но поскольку совпадение с нулем (EFG) есть пустая строка, оно совпадает в любом месте, и это все равно что его вообще не писать. У меня в <> находится (?!EFG).)* любой символ, перед которым опережающая проверка на отсутствие EFG, сколь угодно раз.

Автор: Pori 21.8.2009, 23:39
Валь, используй негативную опережающую проверку. Вот здесь все расписано, для начала самое оно:

http://phpclub.ru/detail/article/regexp_2

А именно по твоему случаю - logo все правильно рассказал. Но если уж очень хочешь сделать через {0}, то можно:

Код

/<(.*?)(?:EFG){0}>/


не забывай ? - этим ты скажешь интерпретатору искать по минимуму. Ну или модификатор U

А с чего вдруг перл начал учить? 

Автор: Logo 4.9.2009, 14:06
Поправка
Код

/<(.*?)(?:EFG){0}>/

(?:EFG){0} Здесь погоды не делает, это аналогично
Код

/<(.*?)>/

Т.е. <ABCD EFG> заберет. 
Модификатора U в перле нет, это PHP.

Автор: Pori 6.9.2009, 22:16
Цитата(Logo @ 4.9.2009,  14:06)
Поправка
Код

/<(.*?)(?:EFG){0}>/

(?:EFG){0} Здесь погоды не делает, это аналогично
Код

/<(.*?)>/

Т.е. <ABCD EFG> заберет. 
Модификатора U в перле нет, это PHP.

Знаю, что не делает - поэтому и написал, если очень хочется с {0}  smile

Сори модификатора U нет. Но все-равно нежадные регулярки никто не отменял ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)