#1 15.05.06 11:49
Диапазоны в регулярных выражениях
мне нужно распознавать диапазоны в ип адресах вида
217.[64-71].1[40-53].[0-244]
как можно это реализовать?
есть идея насчет извращенного варианта,
сделать парсер, который делает, например,
из [64-71] -> (6[4-9]|7[0-1])
1[40-53] -> 1(4[0-9]|4[0-3])
[0-244] -> ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9]|24[0-4])
как видно получается ужас, а как лучше сделать?
Offline
#3 15.05.06 14:26
Re: Диапазоны в регулярных выражениях
iDrum, хм.... можно типа такого:
Код: php:
$ip_ar = explode('.', $user_ip); $addresses = explode(' ', 'тут несколько ип через пробел на совпадения с которыми надо проверить'); for($a=0;$a<count($addresses);$a++) { $cur_ip_ar = explode('.', $addresses[$a]); $c = count($cur_ip_ar); $j = 0; for($i=0;$i<$c;$i++) { if($ip_ar[$i]==$cur_ip_ar[$i]||$cur_ip_ar[$i]=='*') ++$j; if(preg_match('!(^\[\d{1,3}\-\d{1,3}\]$)!', $cur_ip_ar[$i])) { preg_match_all('!\d{1,3}!', $cur_ip_ar[$i], $tmp); if($ip_ar[$i]>=$tmp[0][0] && $ip_ar[$i]<=$tmp[0][1]) ++$j; } } if($c<4 && $cur_ip_ar[$c-1]=='*') $j+=4-$c; if ($j == 4) { exit ('done'); } }

Offline
#7 16.05.06 12:11
Re: Диапазоны в регулярных выражениях
Maq, посмотри, как сделано в viruses.php
Код: php:
if ( preg_match("/217\.71\.14[0-3]\.\d{1,3}/",$name) || preg_match("/192\.168\.[1|2|3|5|6|7]\.\d{1,3}/", $name) )
или ты чего хочешь? задачу скажи лучше, а то нифига не понятно
Offline
#10 16.05.06 14:58
#11 16.05.06 15:04
#12 16.05.06 15:15
Re: Диапазоны в регулярных выражениях
точно...
http://ru.php.net/ip2long
первый же коммент сверху смотри
Offline
#13 16.05.06 15:16
#14 16.05.06 15:24
#15 16.05.06 15:49
#16 16.05.06 15:53
#17 16.05.06 21:41
#18 17.05.06 14:19
#19 18.05.06 09:30
Re: Диапазоны в регулярных выражениях
в общем случае такой классификатор должен работать с максимальной скоростью, т.е. если данные будут храниться в каком-то развернутом внутреннем формате - это нормально. т.е. когда ты пишешь aaa.bbb.[xxx-yyy].ccc - это не регулярное выражение задается, а описывается маска на каком-то встроенном языке (описание которого должно быть доступно), а уже затем эта маска при помощи тех же регулярных выражений преобразуется во внутренний формат.
использование регулярных выражений в качестве внутреннего представления с предложенным синтаксисом - не удачная идея.
p.s. "217.[64-71].1[40-53].[0-244]"
очень понравилось "1[40-53]". а чё не "140+[0-13]"?
в общем случае все что идет после первого задания диапазона - уже не важно, т.е.: aaa.[xxx-yyy].*
Offline
#20 18.05.06 14:11
Re: Диапазоны в регулярных выражениях
...очень понравилось "1[40-53]". а чё не "140+[0-13]"?...
Matrim, ты вообще использовал оператор класса символов? [0-13] это 0,1 и 3.
Кроме того, запись 140+[0-13] подойдет, к примеру, к строке :
попа140000000000000000000000
или
фывавыа1401бяка
, но НЕ к
фывавыа1402бяка
и, тем более НЕ к
фывавыа142кака
А такое: "].*" - вообще не прокатит (любой символ задается точкой, а не звездочкой, знаем же?. А точку xxx.yyy вообще говоря экранировать надо {xxx\.yyy} )
PS. И вообще, оператор [] - это НЕ оператор диапазона. Читай маны по регекспам.
Исправлено Leon (18.05.06 14:12)
Offline
#21 18.05.06 18:10
Re: Диапазоны в регулярных выражениях
и все таки сделал так:
Код: php:
$ip_ar = explode('.', $user_ip); $addresses = explode(' ', 'тут несколько ип через пробел'); for($a=0;$a<count($addresses);$a++) { $cur_ip_ar = explode('.', $addresses[$a]); $c = count($cur_ip_ar); $j = 0; for($i=0;$i<$c;$i++) { if($ip_ar[$i]==$cur_ip_ar[$i]||$cur_ip_ar[$i]=='*') ++$j; //тут добавил $cur_ip_ar[$i] = preg_replace('/^(\d*)\[(\d+)\-(\d+)\](\d*)$/', '[\\1\\2\\4-\\1\\3\\4]', $cur_ip_ar[$i]); if(preg_match('!(^\[\d{1,3}\-\d{1,3}\]$)!', $cur_ip_ar[$i])) { preg_match_all('!\d{1,3}!', $cur_ip_ar[$i], $tmp); if($ip_ar[$i]>=$tmp[0][0] && $ip_ar[$i]<=$tmp[0][1]) ++$j; } } if($c<4 && $cur_ip_ar[$c-1]=='*') $j+=4-$c; if ($j == 4) { exit ('done'); } }
так как понимают выражения типа:
10.*
10.200.1[4-5]0.*
192.168.[0-255].*
10.*.*.*
и т.п.
Offline
#22 19.05.06 02:21
Re: Диапазоны в регулярных выражениях
Leon написал(а):
...очень понравилось "1[40-53]". а чё не "140+[0-13]"?...
цитируйте полностью, а не кусками
Matrim написал(а):
p.s. "217.[64-71].1[40-53].[0-244]"
очень понравилось "1[40-53]". а чё не "140+[0-13]"?
здесь говорится о языке описания маски ip адресов, взятое из первого поста. этот язык не является регулярным выражением, т.е. вот тут:
Maq написал(а):
мне нужно распознавать диапазоны в ип адресах вида
217.[64-71].1[40-53].[0-244]
написано не регулярное выражение, а ip адрес в какой-то расширенной нотации.
исходя из этого упражнения вида:
Leon написал(а):
Matrim, ты вообще использовал оператор класса символов? [0-13] это 0,1 и 3.
Кроме того, запись 140+[0-13] подойдет, к примеру, к строке :
попа140000000000000000000000
или
фывавыа1401бяка
, но НЕ к
фывавыа1402бяка
и, тем более НЕ к
фывавыа142кака
А такое: "].*" - вообще не прокатит (любой символ задается точкой, а не звездочкой, знаем же?. А точку xxx.yyy вообще говоря экранировать надо {xxx\.yyy} )
PS. И вообще, оператор [] - это НЕ оператор диапазона.
в данном случае бесполезны, т.к. обсуждается идея вообще использования регулярных выражений в классификаторе, а не синтаксис какого-то выражения. так что рассуждения про точки и звездочки - мимо кассы, не нужно разбирать как регулярное выражение то, что таковым не является (кстати, весь написанный мною в этом посте текст тоже не является регулярным выражением, большая часть - это классический русский, т.е. если и искать в нем ошибки, то только с точки зрения русского языка, а не синтаксиса регулярных выражений)
Leon написал(а):
Читай маны по регекспам.
временами пишу на перле и использую регулярные выражения, доку читать приходится, т.к. помнить все сложно и не нужно, нужно знать, где можно найти нужное (вот так вот многоэтажно)
в свою очередь могу рекомендовать форум, на котором можно писать не вдаваясь в смысл и не пользуясь головой: http://hostel.nstu.ru/viewforum.php?id=11
Offline

