Perl Регулярное выражение для диапазона IP-адресов - PullRequest
1 голос
/ 16 декабря 2010

У меня есть данные интернет-трафика для анализа.Мне нужно анализировать только те пакеты, которые находятся в определенном диапазоне IP.Итак, мне нужно написать if заявление.Я полагаю, мне нужно регулярное выражение для условия теста.Мои знания о регулярных выражениях немного слабые.Может кто-нибудь сказать мне, как бы я построить регулярное выражение для этого условия.Примерный диапазон может быть как

Group A
56.286.75.0/19 
57.256.106.0/21 
64.131.14.0/22 

Group B
58.176.44.0/21 
58.177.92.0/19 

Оператор if будет выглядеть как

if("IP in A" || "IP in B") {
        do something
}

else { do something else }

, поэтому мне потребуется сделать эквивалентное регулярное выражение для "IP в A" и "IPв условиях B ".

Ответы [ 4 ]

8 голосов
/ 16 декабря 2010

Я не думаю, что регулярные выражения предоставляют много преимуществ для этой проблемы.

Вместо этого используйте модуль Net :: Netmask. Метод match должен делать то, что вы хотите.

1 голос
/ 16 декабря 2010

Я делаю что-то вроде:

use NetAddr::IP;

my @group_a = map NetAddr::IP->new($_), @group_a_masks;
...
my $addr = NetAddr::IP->new( $ip_addr_in );
if ( grep $_->contains( $addr ), @group_a ) {
    print "group a";
}

Я выбрал NetAddr :: IP over Net :: Netmask для поддержки IPv6.

1 голос
/ 16 декабря 2010

Я должен повторить несогласие с использованием регулярных выражений для проверки IP-адресов ... однако, есть способ вытащить IP-адреса из текста:

qr{
  (?<!\d)             # No digit having come immediately before
  (?: [1-9] \d?       # any one or two-digit number
  |   1 \d \d         # OR any three-digit number starting with 1
  |   2 (?: [0-4] \d  # OR 200 - 249
        |   5 [0-6]   # OR 250 - 256
        )
  )
  (?: \.                 # followed by a dot
      (?: [1-9] \d?      # 1-256 reprise...
      |   1 \d \d 
      |   2 (?: [0-4 \d
            |   5 [0-6]
            )
      )
  ){3}     # that group exactly 3 times
  (?!\d)   # no digit following immediately after         
}x
;

Но, учитывая эту общую схему, мы можемпостроить парсер IP.Но для данных «диапазонов» я бы не сделал ничего, кроме следующего:

A => qr{
  (?<! \d )
  (?: 56\.186\. 75
  |   57\.256\.106
  |   64\.131\. 14
  )
  \.
  (?: [1-9] \d?
  |   1 \d \d
  |   2 (?: [0-4] \d
        |   5 [0-6]
        )
  )
  (?! \d )
  }x

B => qr{
  (?<! \d )
  58 \.
  (?: 176\.44
  |   177\.92
  )
  \.
  (?: [1-9] \d?
  |   1 \d \d
  |   2 (?: [0-4] \d
        |   5 [0-6]
        )
  )
  (?! \d )
  }x
0 голосов
/ 16 декабря 2010

Мартин прав, используйте Net :: Netmask. Если вы действительно хотите использовать регулярное выражение, хотя ...

$prefix = "192.168.1.0/25";
$ip1 = "192.168.1.1";
$ip2 = "192.168.1.129";

$prefix =~ s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\/([0-9]+)/$mask=(2**32-1)<<(32-$5); $1<<24|$2<<16|$3<<8|$4/e;
$ip1 =~ s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/$1<<24|$2<<16|$3<<8|$4/e;
$ip2 =~ s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/$1<<24|$2<<16|$3<<8|$4/e;

if (($prefix & $mask) == ($ip1 & $mask)) {
  print "ip1 matches\n";
}
if (($prefix & $mask) == ($ip2 & $mask)) {
  print "ip2 matches\n";
}
...