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


Автор: amg 23.8.2007, 11:38
Один молодой (судя по правописанию) человек задал любопытный вопрос:
Код

... порверить содержит ли строка ip но который не начинается с 192.168.
Как модернизировать вот это \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
Проверка должна осуществляться один рег. выражением объязательно.
В надежде, что найдется решение более удачное, чем мое, переадресую вопрос сюда.

Автор: Nab 23.8.2007, 11:46
если задачка практическая то она безсмысленна, если чисто на интерес, то я все одно не стал бы мучаться  smile и сделал бы через and

Автор: Nab 23.8.2007, 12:30
я имею ввиду что вполне адекватна запись IP в шестнадцетиричной или восьмиричной форме, или еще как, хотя этим практически никто и не пользуеться smile

Автор: fantome 23.8.2007, 13:36
amg
а если так:
Код

$str =~ m/d{,3}\.d{,3}\.d{,3}\.d{,3}/;

Автор: amg 23.8.2007, 15:27
Не. Такой синтаксис регулярных выражений перл совсем не так, как мне хотелось бы, воспринимает.
Фактически, нужно составить одно регулярное выражение, результатом работы которого было бы то же самое, что и выражения
Код

$str =~ m/(\d{1,3}\.\d{1,3})\.\d{1,3}\.\d{1,3}/ and ($1 ne '192.168');

Автор: fantome 24.8.2007, 12:05
amg
хм... у меня на твою конструкцию
Код

and ($1 ne '192.168')

ругань идет....
Цитата

Useless use of string ne in void context at ip_check.pl line 7.


А вот так я попробовал реализовать то, что хотелось.... 
Код

#!/usr/bin/perl -w

my $str = "64 bytes from ya.ru (213.180.204.8): icmp_seq=1 ttl=58 time=3.10 ms";
my $ip;

$str =~ m/(\d+?\.\d+?\.\d+?\.\d+?)/;

if ( $1 =~ m/192\.168/ )
{ printf "invalid ip address\n";
}
else
{ $ip = $1;
  printf "ip = $ip\n";
}

exit 0;
END;

Как бы теперь всё это свернуть???

Автор: Shaggie 24.8.2007, 12:21
Код

print 'correct' if $str!~/(192\.168)/ and $str=~/$1\.\d{1,3}\.\d{1,3}/;

Как-то так.

Добавлено через 1 минуту и 6 секунд
но это опять две регулярки... подумаем ещё

Автор: Shaggie 24.8.2007, 13:39
Предыдущий мой код не будет работать, если в строке есть последовательность символов "192.168", не важно, относится ли она к этому ip...

Второй вариант:
Код

print $str if $str=~s/((\d{1,3}\.\d{1,3})\.\d{1,3}\.\d{1,3})/$1 if $2 ne '192.168'/e;


Добавлено через 2 минуты и 25 секунд
э-эхх... опять не то. ещё подумаю...

Автор: amg 24.8.2007, 13:53
fantome, не будет ругани, если применять правильно:
Код

print 'correct' if $str =~ /(\d{1,3}\.\d{1,3})\.\d{1,3}\.\d{1,3}/ and ($1 ne '192.168');

Shaggie, как эту задачку решить в принципе, понятно. Суть моего вопроса в том, чтобы сделать это одним регулярным выражением без чего бы то ни было более. Т.е. условие нужно вставить внутрь регулярки.

Автор: Shaggie 27.8.2007, 06:47
Цитата(amg @  23.8.2007,  12:38 Найти цитируемый пост)
... порверить содержит ли строка ip но который не начинается с 192.168.
Как модернизировать вот это \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
Проверка должна осуществляться один рег. выражением объязательно.

Условия бы поподробнее... там просто адрес или он в строке лога? Один адрес или несколько? как выводить результат?

Поэтому танцую от себя.
В строке может быть сколько угодно всего, надо вытащить все ip адреса, которые не начинаются с '192.168'. Не буду напоминать, что регулярка на валидность ip выглядит хитрее, здесь всё упрощено.
Результаты пишу в массив, после прогона строки (всех строк... как там это надо?) вывожу массив на экран.
Регулярка изменяет исходную строку, поэтому строки надо прогонять не как есть, а их копии - либо через foreach массив строк, либо как в моём примере
Код

$str='192.169.0.1 + maybe 192.184.14.76 and 192.168.45.45';
@arr=();
($temp = $str) =~ s/((\d{1,3}\.\d{1,3})\.\d{1,3}\.\d{1,3})/push(@arr,$1) if $2 ne '192.168'/eg;
print join\"\n\",@arr;"

Цитата(вывод)

192.169.0.1
192.184.14.76

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