Вопрос по ip, perl, regex – Регулярное выражение Perl для соответствия IP-адресу

10

Я написал этот код, но он не работает. Может кто-то указать на проблему?

<code>sub match_ip()
{
  my $ip = "The IP address is 216.108.225.236:60099";
  if($ip =~ /(\d{1-3}\.\d{1-3}\.\d{1-3}\.\d{1-3}\:\d{1-5})/)
  {
      print "$1\n";
  }
}
</code>

РЕДАКТИРОВАТЬ: Я хотел просто извлечь IP-адрес, а не делать какие-либо проверки.

Здесь больше пары вопросов. Используйте один из модулей или посмотрите на все, что модули делают, чтобы сделать это правильно. :) brian d foy
Вы пытаетесь подтвердить или просто извлечь IP-адрес? Потому что он делает ужасную работу по сравнению с первым. ikegami
Вместо написания собственного регулярного выражения вы можете рассмотреть возможность использования хорошо документированного и протестированного модуля f.ex.Regexp :: Общие dgw
Ну, вы также не хотите извлекать вещи, которые не могут быть IP-адресами, поэтому проверка, которая очень проста, помогает уменьшить количество ложных срабатываний. brian d foy
Я хочу просто извлечь, а не проверить cppcoder

Ваш Ответ

12   ответов
5

Regexp::Common::net частьRegexp::Common, может быть, это регулярное выражение, которое вы хотите.

11

{1-3} в{1,3} то же самое для{1-5} ->{1,5}

Для downvoter: есть причина? Toto
@ M42 - Мой пост (ответ) внизу был отклонен без причины #briandfoy и его последователями, поэтому я попытался прокомментировать ваш ответ, чтобы он показал, что эти ответы хорошие. Ваш ответ был самым первым, поэтому вы заслуживаете одобрения и одобрения. Ωmega
@ briandfoy - Это приемлемый ответ и для вас? Как я упоминал ранее, иногда OP хочет простое решение, которое решает его проблему, а не сложный код. В этом случае проверка IP не требуется, так как, вероятно, OP необходимо проанализировать вывод, содержащий действительные IP-адреса. Так что этот ответ - именно то, что искал ОП. Спасибо M42 за простой ответ, отвечающий потребностям ОП. Ωmega
@ M42 - Правильно, M42. Это было решено с помощью регулярных выражений, как и требовал OP. К сожалению, #briandfoy очень часто пытается изменить простые задачи на сложные вопросы, что в большинстве случаев не то, что хотят OP. Ωmega
@ briandfoy: Вы правы, но это то, чего хочет ОП, решает проблему регулярных выражений. Toto
3

Кроме того, вы можете использоватьData::Validate::IP с предупреждением, что он не распознает порт, поэтому вам придетсяsplit на:.

use strict;
use warnings;
use Data::Validate::IP;

my $ip_with_port="216.108.225.236:60099";
my $ip=(split /:/,$ip_with_port)[0];

my $validator=Data::Validate::IP->new;

if($validator->is_ipv4($ip))
{
  print "Yep, $ip is a valid IPv4 address.\n";
}
else
{
  print "Nope, $ip is not a valid IPv4 address.\n";
}

Вывод:

Yep, 216.108.225.236 is a valid IPv4 address.
Вопрос ОП заключается в том, чтобы найти совпадение (регулярное выражение), а не проверять IP-адрес. Ваш сценарий использует IP-адрес в качестве входных данных, но входные данные OP - это строка, которая может содержать IP-адрес, но не только IP-адрес. Ωmega
@ stackoverflow - TIMTOWTDI. Кроме того, а) ОП пытался собрать регулярное выраженидля того, чтоб проверить IP-адрес и б) если вы посмотрите на исходный код Data :: Validate :: IP, он использует регулярные выражения. Так что мой ответявляетс важно, нравится тебе это или нет. user554546
Почему такие сильные слова? Мне нравится ваш ответ, но я прокомментировал ваш ответ по одной-единственной причине - я не вижу в вопросе ОП никаких замечаний о том, что он ищет подтверждение IP ... и я не вижу его там даже сейчас, когда ваш комментарии о том, что ОП просит об этом. В любом случае ... Ваш код является правильным решением для проверки IP. Период. Просто не уверен, что именно этого хочет ОП. Может, он вернется к нам и уточнит свои нужды ... Ωmega
2

Заменить тире запятыми.

/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5})/
0
#!/usr/bin/perl

$str = 'IP address is : 70.21.311.105';

    if ($str =~ m/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) {
        if ($1 <= 255 && $2 <= 255 && $3 <= 255 && $4 <= 255 ) {
            print "Valid $str\n";
    } else {
          print "invalid IP $str\n";
    }
}


__END__
Не нужно второгоif condition, который может быть написан с первым, как этотif($str =~ m/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ && ($1<=255 && $2<=255 && $3<=255 && $4<=255 )) serenesat
2

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

Вот более короткая версия вашего регулярного выражения, со своими собственными подводными камнями:

while (my $ip = <DATA>)  {
    chomp $ip;
    # older version
    # if($ip =~ /(\d{1-3}\.\d{1-3}\.\d{1-3}\.\d{1-3}\:\d{1-5})/)

    # see below for explanation
    if ($ip =~ /\b(\d{1,3}(?:\.\d{1,3}){3}:\d{1,5})\b/)
    {
        print "$ip - matches\n";
    } else {
        print "$ip - does not match\n";
    }
}

__DATA__
216.108.225.236:60099
4.2.2.1:1
216.108.225.236:0
1216.1108.1225.1236:1234
216.108.225.236x:123
9216.108.225.236:8472
10.10.10.10

Полученные результаты

216.108.225.236:60099 - matches
4.2.2.1:1 - matches
216.108.225.236:0 - matches
1216.1108.1225.1236:1234 - does not match
216.108.225.236x:123 - does not match
9216.108.225.236:8472 - does not match
10.10.10.10 - does not match

Explanation:

/\b             # word boundary
(               # start memory capture group 1
\d{1,3}         # one to three digits, first octat
(:?             # start non memory capture group, notice ?:
  \.\d{1,3}     # a literal dot followed by an ip octet
)               # end non memory capture group
{3}             # three times of dots and ip octets
:               # match a colon
\d{1,5}         # port number, one to five digits
)               # end of memory capture group 1
\b              # word boundary

Надеюсь это поможет

Если вы собираетесь проделать такую большую работу, вы можете также настроить регулярное выражение на правильный диапазон цифр. Вы должны также проверить наличие таких вещей, как 127.1, действительный адрес, который меня укусил, когда я делал подобные вещи неправильно. brian d foy
@ Will, Брайан: ты, должно быть, пропустил "так как я доверял / подавал ввод" в описании Ашиша. Также иногда использование внешних модулей не возможно, не приветствуется, не желательно, и в этом случае стоит упомянуть «ручное» решение. taiko
Ваши данные испытаний неполны. Что-то типа333.108.225.236:123 неверный IP-адрес, но прошел бы проверку. Will Sheppard
0

Попробуй это

$variablename=~m/((((0-9)|((1-9)(0-9))|(1([0-9]){2})|(2[0-4][0-9])|(2[5][0-5]))\.){3})((0-9)|((1-9)(0-9))|(1([0-9]){2})|(2[0-4][0-9])|(25[0-5]))/)
Пожалуйста, отформатируйте свой код как код. Nic Hartley
0

http: //metacpan.org/pod/Regexp :: Общие :: Чистая

Если вы извлекаете IP-адрес, который не является IP-адресом ... вы не извлекаете правильную вещь.

0
use strict;
use warnings;
open(FH,"<fileName.txt") or die "file not found ,$_";
while(my $line=<FH>)
{
push(my @arr,($line));
foreach my $arrVal (@arr)
{           
if($arrVal=~/IPv4 Address(?=.*\b((25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2  [0-4]\d|[0-1]?\d?\d)){3})\b)/)
{
print "$arrVal\n";
}
}
Хотя этот код может ответить на вопрос, предоставляя дополнительный контекст относительноЗаче и / илика ответ на вопрос значительно улучшит его долгосрочную ценность. Пожалуйстаредактироват ваш ответ, чтобы добавить объяснение. Toby Speight
1

Это может помочь:

my $ip = "195.249.61.14";

my @ips = (
    "set protocols bgp group IBGP-RRCL-CUSTOMER neighbor 195.249.61.142",
    "set protocols bgp group IBGP-RRCL-CUSTOMER neighbor 195.249.61.14",
    "set protocols bgp group IBGP-RRCL-CUSTOMER neighbor 195.249.61.141"
);

foreach (@ips) {
   print "$_\n" if ( /\b$ip\b/ );
}

Выход

set protocols bgp group IBGP-RRCL-CUSTOMER neighbor 195.249.61.14
-1

чтобы убедиться, что квад не больше 255, он также «повторно» использует сопоставление цифр вместо копирования их 4 раза.

my $rx = qr/^(?!(\.))(\.?(\d{1,3})(?(?{$^N > 255})(*FAIL))){4}$/;
if('192.168.1.2' =~ $rx){
  print "OK\n";
}

Он использует несколько функций из сопоставления регулярных выражений perl (man perlre):

(* FAIL): останавливает сопоставление с образцом и завершается ошибкой (? (условие) ...): условное совпадение (? {code}): используется в этом условии
Это не получается за $ rx = "27,34" Jim True
-2
$ip = "10.255.256.1";

# will accept valid ips
if ($ip =~ m/^([1|2][0-9]{1,2})\.([0-255]{1,3}\.){2}[0-255]{1,3}/ && ($1 <=255)) {

  print "This is a valid ip: $ip \n";
 } else {
   print "This is not a valid ip: $ip \n";
}
-1 Ты плохо изобретаешь воду. Это запрещает любой адрес, чей первый октет> = 200, для начинающих. tripleee
Я думаю, вы должны узнать об IP-адресе. Адрес класса C не будет> = 200. Обычно мы будем проверять только адрес класса c. Дайте мне знать, когда вы будете проверять другой адрес класса user2662353
С чем связаны сети класса C? В современном мире сети в любом случае бесклассовые. И адрес примера OP - 216.x.x.x. А также[0-255] в регулярном выражении не делает то, что вы думаете, что делать. tripleee

Похожие вопросы