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


Автор: kalabro 21.1.2010, 01:49
Доброй ночи.
Не знала, как назвать тему.

Есть строка:
Код
"Фрукты: яблоко, груша, апельсин; Автомобили: ВАЗ, УАЗ, ГАЗ;"

Хочу выбрать только все фрукты, т.е. получить массив 
Код
{"яблоко"; "груша"; "апельсин"}

Пример сильно упрошен smile
Сейчас я делаю так: ищу «Фрукты:» и первую точку с запятой после них, выделяю эту подстроку и там уже спокойненько разбираю свои фрукты, но почему-то кажется, что можно одним регулярным выражением обойтись.

Спасибо, что прочли ;)

Автор: krypt3r 21.1.2010, 07:42
Код

my $str = "Фрукты: яблоко, груша, апельсин; Автомобили: ВАЗ, УАЗ, ГАЗ;";
my ($fruits) = $str =~ /Фрукты:\s*(.+?);/;
my @fruits = split /,\s*/, $fruits;
print for @fruits;

Автор: kalabro 21.1.2010, 08:04
krypt3r, такой вариант я и сама реализовала, о чем и сообщила в первом посте ;)
Вопрос в том, чтобы как-нибудь так написать регулярное выражение, чтобы сразу возвращался такой массив. Зачем? — Интересно  smile 

Автор: sir_nuf_nuf 21.1.2010, 12:21
Вот так:

Код

use utf8;
my $str = "Фрукты: яблоко, груша, апельсин; Автомобили: ВАЗ, УАЗ, ГАЗ;";
my @fruits = $str =~ /\s*(\w+?)[,;](?=.*Авто)/ig;
binmode STDOUT, ":utf8";
print join " : ",  @fruits;


Вооще немного кривовато, но работает.
Операция сопоставления с регуляркой =~ вызванная в списковом контексте возвращает массив совпадающих подстрок. Это не точная формулировка, RTFM.

P.S. utf8 - можно убрать.. это для меня было

Автор: Logo 21.1.2010, 20:30
Ну, раз интересно:
A
Код

$_ = "Фрукты: яблоко, груша,  апельсин; Автомобили: ВАЗ, УАЗ, ГАЗ;";
$, = ",";
local our @frutis; #важно - @frutis не должно быть my, либо это место должно выполнятся в программе только один раз
() = m/Фрукты:\s*(?:([^,;]*?)\s*,\s*(?{push @frutis, $^N}))*+([^,;]+)\s*;(?{push @frutis, $^N})/;
print @frutis;


B
Код

$_ = "Фрукты: яблоко, груша, апельсин; Автомобили: ВАЗ, УАЗ, ГАЗ;";
$, = ",";
print m/(?:Фрукты:|\G(?<!;))\s*([^,;]+?)\s*[,;]/g;

Автор: RomanCh 13.2.2010, 15:04
Раз уж тема создана "ради интереса", то и сроков давности она не имеет smile Вот ещё вариант, ИМХО простой, достаточно надёжный и очевидный:
Код

# Ищем элементы под именем 'need'.
$s = 'any-items: i1, i2, i3, i4; need: n1, n2, n3, n4; not-need: nn1, nn2, nn3, nn4';
$s =~ m#\bneed:\s*([^;]+)(?{@need = split /,\s*/, $1})#;
print join('|',@need),"\n";

Результатом будет, как и ожидалось: n1|n2|n3|n4

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