Проверка адресов IPv4 с помощью regexp

Я пытался получить эффективное регулярное выражение для проверки IPv4, но без особого успеха. В какой-то момент мне показалось, что с меня хватит!--1-->, но это дает некоторые странные результаты:

[chris@helios bashscripts]$ grep --version
grep (GNU grep) 2.7


[chris@helios bashscripts]$ grep -E 'b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(.|$)){4}b' <<< 192.168.1.1
192.168.1.1
[chris@helios bashscripts]$ grep -E 'b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(.|$)){4}b' <<< 192.168.1.255
192.168.1.255
[chris@helios bashscripts]$ grep -E 'b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(.|$)){4}b' <<< 192.168.255.255
[chris@helios bashscripts]$ grep -E 'b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(.|$)){4}b' <<< 192.168.1.2555
192.168.1.2555

Я сделал поиск, чтобы узнать, было ли это уже задано и ответили, но другие ответы, похоже, просто показывают, как определить 4 группы из 1-3 чисел или не работают для меня.

какие идеи? Спасибо!

26 ответов


у вас уже есть рабочий ответ, но на всякий случай вам интересно, что было не так с вашим оригинальным подходом, ответ заключается в том, что вам нужны круглые скобки вокруг вашего чередования в противном случае (\.|$) требуется, только если число меньше 200.

'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
    ^                                    ^

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

принимать:

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01

отклонение:

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
3...3

попробуйте онлайн с модульными тестами:https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1


Regex не является инструментом для этой работы. Лучше было бы написать парсер, который отделяет четыре числа и проверяет, что они находятся в диапазоне [0,255]. Нефункциональные тестирую уже нечитаю!


IPv4-адрес (точный захват) Матчи 0.0.0.0 по 255.255.255.255 Используйте это регулярное выражение для сопоставления IP-номеров с точностью. Каждый из 4 номеров хранится в группе захвата, так что вы можете получить к ним доступ для дальнейшей обработки.

\b
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
\b

взято из библиотеки Jgsoft RegexBuddy

Edit: это (\.|$) часть кажется wierd


Я искал что - то подобное для IPv4-адресов-регулярное выражение, которое также прекратило проверку часто используемых частных ip-адресов (192.168.X. y, 10.х.г.з 172.16.X. y) так использовал отрицательный взгляд aheads для достижения этого:

(?!(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.).*)
(?!255\.255\.255\.255)(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|[1-9])
(\.(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|\d)){3}

(Они должны быть на одной строке, конечно, отформатированы для целей удобочитаемости на 3 отдельных строках)

Debuggex Demo

Он не может быть оптимизирован для скорости, но работает хорошо, если только ищу "реальные" интернет-адреса.

вещи, которые будут (и должны) не выполнено:

0.1.2.3         (0.0.0.0/8 is reserved for some broadcasts)
10.1.2.3        (10.0.0.0/8 is considered private)
172.16.1.2      (172.16.0.0/12 is considered private)
172.31.1.2      (same as previous, but near the end of that range)
192.168.1.2     (192.168.0.0/16 is considered private)
255.255.255.255 (reserved broadcast is not an IP)
.2.3.4
1.2.3.
1.2.3.256
1.2.256.4
1.256.3.4
256.2.3.4
1.2.3.4.5
1..3.4

IPs, которые будут (и должны) работать:

1.0.1.0         (China)
8.8.8.8         (Google DNS in USA)
100.1.2.3       (USA)
172.15.1.2      (USA)
172.32.1.2      (USA)
192.167.1.2     (Italy)

при условии, если кто-то еще ищет проверку "Интернет-IP-адреса, не включая общие частные адреса"


новая и улучшенная более короткая версия

^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\.(?!$)|$)){4}$

он использует отрицательный lookahead (?!) чтобы удалить случай, когда ip может закончиться .

ответ

^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}
    (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$ 

Я думаю, что это самое точное и строгое регулярное выражение, оно не принимает такие вещи, как 000.021.01.0. похоже, что большинство других ответов здесь делают и требуют дополнительного регулярного выражения для отклонения случаев, подобных этому-т. е. 0 начальные номера и ip, который заканчивается .


Это немного дольше, чем некоторые, но это то, что я использую для сопоставления адресов IPv4. Просто без компромиссов.

^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$

мне удалось построить регулярное выражение из всех других ответов.

(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)(\.(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)){3}

С маской подсети :

^$|([01]?\d\d?|2[0-4]\d|25[0-5])\
.([01]?\d\d?|2[0-4]\d|25[0-5])\
.([01]?\d\d?|2[0-4]\d|25[0-5])\
.([01]?\d\d?|2[0-4]\d|25[0-5])
((/([01]?\d\d?|2[0-4]\d|25[0-5]))?)$

(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))

    const char*ipv4_regexp = "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b";

я адаптировал регулярное выражение, взятое из библиотеки Jgsoft RegexBuddy, к языку C (regcomp / regexec), и я узнал, что он работает, но в некоторых ОС, таких как Linux, есть небольшая проблема. Это регулярное выражение принимает IPv4-адрес, такой как 192.168.100.009, где 009 в Linux считается восьмеричным значением, поэтому адрес не тот, который вы думали. Я изменил регулярное выражение следующим образом:

    const char* ipv4_regex = "\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\b";

использование этого обычного expressione теперь 192.168.100.009 недопустимо IPv4-адрес, хотя 192.168.100.9 ОК.

Я также изменил регулярное выражение для многоадресного адреса, и это следующее:

    const char* mcast_ipv4_regex = "\b(22[4-9]|23[0-9])\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]?)\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\b";

Я думаю, вам нужно адаптировать регулярное выражение к языку, который вы используете для разработки своего приложения

Я привел пример на java:

    package utility;

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class NetworkUtility {

        private static String ipv4RegExp = "\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d?)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d?)\b";

        private static String ipv4MulticastRegExp = "2(?:2[4-9]|3\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d?|0)){3}";

        public NetworkUtility() {

        }

        public static boolean isIpv4Address(String address) {
            Pattern pattern = Pattern.compile(ipv4RegExp);
            Matcher matcher = pattern.matcher(address);

            return matcher.matches();
        }

        public static boolean isIpv4MulticastAddress(String address) {
             Pattern pattern = Pattern.compile(ipv4MulticastRegExp);
             Matcher matcher = pattern.matcher(address);

             return matcher.matches();
        }
    }

-bash-3.2$ echo "191.191.191.39" | egrep 
  '(^|[^0-9])((2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)\.{3}
     (2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)($|[^0-9])'

>> 191.191.191.39

(Это DFA, который соответствует всему пространству addr (включая трансляции и т. д.) является ничем иным.


Я думаю, что этот самый короткий.

^(([01]?\d\d?|2[0-4]\d|25[0-5]).){3}([01]?\d\d?|2[0-4]\d|25[0-5])$

Я нашел этот образец очень полезным, кроме того, он позволяет различные обозначения ipv4.

пример кода с использованием python:

    def is_valid_ipv4(ip4):
    """Validates IPv4 addresses.
    """
    import re
    pattern = re.compile(r"""
        ^
        (?:
          # Dotted variants:
          (?:
            # Decimal 1-255 (no leading 0's)
            [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
          |
            0x0*[0-9a-f]{1,2}  # Hexadecimal 0x0 - 0xFF (possible leading 0's)
          |
            0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
          )
          (?:                  # Repeat 0-3 times, separated by a dot
            \.
            (?:
              [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
            |
              0x0*[0-9a-f]{1,2}
            |
              0+[1-3]?[0-7]{0,2}
            )
          ){0,3}
        |
          0x0*[0-9a-f]{1,8}    # Hexadecimal notation, 0x0 - 0xffffffff
        |
          0+[0-3]?[0-7]{0,10}  # Octal notation, 0 - 037777777777
        |
          # Decimal notation, 1-4294967295:
          429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
          42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
          4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
        )
        $
    """, re.VERBOSE | re.IGNORECASE)
    return pattern.match(ip4) <> None

((\.|^)(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0$)){4}

это регулярное выражение не будет принимать 08.8.8.8 или 8.08.8.8 или 8.8.08.8 или 8.8.8.08


находит допустимые IP-адреса, пока IP-адрес обернут вокруг любого символа, кроме цифр (позади или впереди IP-адреса). Создано 4 Backreferences: $+{first}.$+{второй.}$+{третий.}$+{forth}

Find String:
#any valid IP address
(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))
#only valid private IP address RFC1918
(?<IP>(?<![\d])(:?(:?(?<first>10)[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5])))|(:?(?<first>172)[\.](?<second>(:?1[6-9])|(:?2[0-9])|(:?3[0-1])))|(:?(?<first>192)[\.](?<second>168)))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Notepad++ Replace String Option 1: Replaces the whole IP (NO Change):
$+{IP}

Notepad++ Replace String Option 2: Replaces the whole IP octect by octect (NO Change)
$+{first}.$+{second}.$+{third}.$+{forth}

Notepad++ Replace String Option 3: Replaces the whole IP octect by octect (replace 3rd octect value with 0)
$+{first}.$+{second}.0.$+{forth}
NOTE: The above will match any valid IP including 255.255.255.255 for example and change it to 255.255.0.255 which is wrong and not very useful of course.

замена части каждого octect с фактическим значением, однако вы можете создать свой собственный найти и заменить, который является фактическим полезным для ammend IPs в текстовых файлах:

for example replace the first octect group of the original Find regex above:
(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<first>10)

and
(?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<second>216)
and you are now matching addresses starting with first octect 192 only

Find on notepad++:
(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

вы все еще можете выполнить замену с помощью групп back-referece точно так же, как до.

вы можете получить представление о том, как выше сопоставлены ниже:

cat ipv4_validation_test.txt
Full Match:
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0


Partial Match (IP Extraction from line)
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


NO Match
1.1.1.01
3...3
127.1.
192.168.1..
192.168.1.256
da11.15.112.2554adfdsfds
da311.15.112.255adfdsfds

используя grep, вы можете увидеть результаты ниже:

From grep:
grep -oP '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0
1.2.3.4
10.216.24.23
11.15.112.255
10.216.24.23


grep -P '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


#matching ip addresses starting with 10.216
grep -oP '(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
10.216.1.212
10.216.24.23
10.216.24.23

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.)){3}+((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$


выше будет регулярное выражение для ip-адреса, как: 221.234.000.112 также для 221.234.0.112, 221.24.03.112, 221.234.0.1


вы можете представить себе все виды адресов, как указано выше


Я бы использовал PCRE и define ключевые слова:

/^
 ((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))$
 (?(DEFINE)
     (?<byte>25[0-5]|2[0-4]\d|[01]?\d\d?))
/gmx

демо:https://regex101.com/r/IB7j48/2

причина этого в том, чтобы избежать повторения (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) рисунок в четыре раза. Другие решения, такие как приведенное ниже, работают хорошо, но они не охватывают каждую группу, как это было бы предложено многими.

/^((\d+?)(\.|$)){4}/ 

единственный способ иметь 4 группы захвата, чтобы повторить рисунок в четыре раза:

/^(?<one>\d+)\.(?<two>\d+)\.(?<three>\d+)\.(?<four>\d+)$/

захват для IPv4 в Perl, поэтому очень легко

$ echo "Hey this is my IP address 138.131.254.8, bye!" | \
  perl -ne 'print "[, , , ]" if \
    /\b((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))
     (?(DEFINE)
        \b(?<byte>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
    /x'

[138, 131, 254, 8]

самое точное, простое и компактное регулярное выражение IPv4, которое я могу себе представить, это

^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$

но как насчет производительности / эффективности ... Прости, я не знаю, какая разница?


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

это самое простое, что я мог придумать:

Python / Ruby / Perl:

/(\d+(\.|$)){4}/

grep-E (GNU Grep 3.1), awk (версия 20070501) и sed:

/([0-9]+(\.|$)){4}/

марионетка позволила это:

/(\d+[\.$]){4}/

попробуйте это:

\b(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.(2[0-5][0-5]|1[0-9][0-9]|[1-9][0-9]|[1-9]))\b

ip address can be from 0.0.0.0 to 255.255.255.255

(((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])[.]){3}((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])$

(0|1)?[0-9][0-9]? - checking value from 0 to 199
2[0-4][0-9]- checking value from 200 to 249
25[0-5]- checking value from 250 to 255
[.] --> represent verify . character 
{3} --> will match exactly 3
$ --> end of string

это regex работает для меня:
"\<((([1-9]|1[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([1-9]|1[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))\>"


IPv4-адрес-очень сложная вещь.

Примечание: отступ и подкладка только для целей иллюстрации и не существуют в реальном регулярном выражении.

\b(
  ((
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )\.){1,3}
  (
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )
|
  (
    [1-3][0-9]{1,9}
  |
    [1-9][0-9]{,8}
  |
    (4([0-1][0-9]{8}
      |2([0-8][0-9]{7}
        |9([0-3][0-9]{6}
          |4([0-8][0-9]{5}
            |9([0-5][0-9]{4}
              |6([0-6][0-9]{3}
                |7([0-1][0-9]{2}
                  |2([0-8][0-9]{1}
                    |9([0-5]
    ))))))))))
  )
|
  0[Xx]0*[0-9A-Fa-f]{1,8}
|
  0+[1-3]?[0-7]{,10}
)\b

эти адреса IPv4 обоснованы выше регулярное выражение.

127.0.0.1
2130706433
0x7F000001
017700000001
0x7F.0.0.01 # Mixed hex/dec/oct
000000000017700000001 # Have as many leading zeros as you want
0x0000000000007F000001 # Same as above
127.1
127.0.1

это отверг.

256.0.0.1
192.168.1.099 # 099 is not a valid number
4294967296 # UINT32_MAX + 1
0x100000000
020000000000

mysql> select ip from foo where ip regexp '^\s*[0-9]+\.[0-9]+\.[0-9]+\.[0-9]\s*';

String zeroTo255 = "([0-9]|[0-9][0-9]|(0|1)[0-9][0-9]|2[0-4][0-9]|25[0-5])";

it can contain single digit i.e ([0-9]);  
It can contain two digits i.e ([0-9][0-9]); 
range is (099 to 199)i.e((0|1)[0-9][0-9]); 
range is (200 - 249) i.e (2[0-9][0-9]) ; 
range is (250-255) i.e(25[0-5]);