IP-адреса

IP-адрес — это строка со строгой структурой, состоящая из числовых блоков, разделённых точками. Формат IPv4 включает четыре октета:

192.168.0.1

Каждый блок содержит число от 0 до 255. Простая текстовая проверка недостаточна, поскольку строка 999.999.999.999 формально соответствует шаблону число.число.число.число, но не является корректным IP-адресом.

Библиотека Inputmask позволяет:

  • ограничивать ввод структуры IP;
  • автоматически вставлять точки;
  • запрещать недопустимые символы;
  • валидировать диапазоны значений;
  • управлять поведением курсора;
  • создавать динамические маски для IPv4 и IPv6.

Простая маска IPv4

Базовая маска может быть построена через цифровые плейсхолдеры:

<input id="ip">
Inputmask("999.999.999.999").mask("#ip");

Такая маска:

  • разрешает только цифры;
  • автоматически показывает точки;
  • требует ввод четырёх блоков.

Пример:

192.168.001.100

Недостаток такого подхода — отсутствие проверки диапазона 0–255.

Например:

999.999.999.999

будет считаться валидным вводом.


Проверка диапазона октетов

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

Наиболее распространённый шаблон IPv4:

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

Он описывает:

Шаблон Значение
25[0-5] 250–255
2[0-4]\d 200–249
1\d\d 100–199
[1-9]?\d 0–99

Маска IPv4 через Regex

Inputmask поддерживает режим регулярных выражений.

Inputmask({
    regex: "((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})"
}).mask("#ip");

Корректные значения:

127.0.0.1
192.168.1.10
255.255.255.255

Некорректные значения:

256.1.1.1
999.0.0.1
300.400.500.600

Использование alias для IP

Inputmask содержит встроенный alias для IP-адресов.

Inputmask("ip").mask("#ip");

Это наиболее удобный вариант.

Особенности alias:

  • автоматическая проверка диапазонов;
  • корректная обработка точек;
  • ограничение октетов;
  • поддержка неполного ввода;
  • встроенная логика валидации.

Пример работы:

192.168.0.1

Попытка ввести:

300

в одном октете будет отклонена.


Настройка alias IP

Alias поддерживает дополнительные параметры.

Очистка маски при потере фокуса

Inputmask("ip", {
    clearIncomplete: true
}).mask("#ip");

Если пользователь оставил адрес незавершённым:

192.168.

поле будет очищено.


Автоматическое удаление маски

Inputmask("ip", {
    autoUnmask: true
}).mask("#ip");

При получении значения:

input.value

возвращается чистый IP без внутренних служебных символов.


Плейсхолдеры

Inputmask("ip", {
    placeholder: "_"
}).mask("#ip");

Результат:

___.___.___.___

Получение значения IP

Значение с маской

const value = document.getElementById("ip").value;

Пример:

192.168.0.1

Чистое значение

const value = document.getElementById("ip").inputmask.unmaskedvalue();

Для IP результат обычно совпадает:

192.168.0.1

Валидация IP

Inputmask предоставляет метод проверки.

const valid = Inputmask.isValid(
    "192.168.1.1",
    {
        alias: "ip"
    }
);

console.log(valid);

Результат:

true

Проверка некорректного адреса

const valid = Inputmask.isValid(
    "999.999.999.999",
    {
        alias: "ip"
    }
);

console.log(valid);

Результат:

false

Проверка через isComplete

Метод isComplete() определяет, завершён ли ввод.

const complete = document
    .getElementById("ip")
    .inputmask
    .isComplete();

console.log(complete);

Для:

192.168.1.

результат:

false

Обработка событий

Событие complete

Inputmask("ip", {
    oncomplete: function () {
        console.log("IP введён полностью");
    }
}).mask("#ip");

Событие incomplete

Inputmask("ip", {
    onincomplete: function () {
        console.log("Адрес не завершён");
    }
}).mask("#ip");

Событие invalid

Inputmask("ip", {
    onKeyValidation: function (key, result) {
        console.log(key, result);
    }
}).mask("#ip");

Ограничение ввода IPv4

Иногда требуется запретить:

  • ведущие нули;
  • специальные диапазоны;
  • локальные адреса;
  • broadcast-адреса.

Запрет ведущих нулей

Стандартный IP допускает:

001.001.001.001

Но многие интерфейсы требуют:

1.1.1.1

Можно использовать regex:

Inputmask({
    regex: "((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])"
}).mask("#ip");

Разрешение только локальных IP

Пример диапазона:

192.168.x.x

Маска:

Inputmask({
    regex: "192\\.168\\.(25[0-5]|2[0-4][0-9]|[0-9]{1,2})\\.(25[0-5]|2[0-4][0-9]|[0-9]{1,2})"
}).mask("#ip");

Маска для IPv6

IPv6 имеет совершенно другой формат:

2001:0db8:85a3:0000:0000:8a2e:0370:7334

Inputmask не содержит полноценного встроенного alias IPv6, поэтому обычно используется regex.


Простая маска IPv6

Inputmask({
    regex: "[0-9a-fA-F:]{2,39}"
}).mask("#ipv6");

Такая проверка является упрощённой.


Более строгая IPv6-маска

Inputmask({
    regex: "([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}"
}).mask("#ipv6");

Корректный пример:

fe80:0000:0000:0000:0202:b3ff:fe1e:8329

Поддержка сокращённой формы IPv6

IPv6 допускает сокращения:

::1
fe80::1

Полноценное регулярное выражение становится крайне сложным.

В таких случаях обычно применяют:

  • серверную проверку;
  • специализированные валидаторы;
  • комбинирование Inputmask и backend-валидации.

Динамический выбор IPv4/IPv6

Inputmask поддерживает динамические маски.

Inputmask({
    mask: [
        {
            alias: "ip"
        },
        {
            regex: "[0-9a-fA-F:]{2,39}"
        }
    ],
    keepStatic: false
}).mask("#address");

Поле сможет принимать:

192.168.0.1

и:

fe80::1

Маска IP с портом

Часто адрес вводится вместе с портом:

192.168.0.1:8080

Простая маска IP:PORT

Inputmask({
    regex: "((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}):([0-9]{1,5})"
}).mask("#ipport");

Проверка диапазона порта

Корректный диапазон порта:

0–65535

Regex для порта:

6553[0-5]
|655[0-2][0-9]
|65[0-4][0-9]{2}
|6[0-4][0-9]{3}
|[1-5][0-9]{4}
|[0-9]{1,4}

Полная маска:

Inputmask({
    regex:
        "((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\\.){3}" +
        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})" +
        ":" +
        "(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[0-9]{1,4})"
}).mask("#ipport");

Маска CIDR

CIDR-запись:

192.168.0.0/24

Маска IPv4/CIDR

Inputmask({
    regex:
        "((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\\.){3}" +
        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})" +
        "\\/" +
        "(3[0-2]|[12]?[0-9])"
}).mask("#cidr");

Корректные значения:

10.0.0.0/8
192.168.0.0/24
172.16.0.0/16

Производительность regex-масок

Сложные регулярные выражения для IP:

  • увеличивают нагрузку;
  • усложняют обработку курсора;
  • могут вызывать задержки на мобильных устройствах.

Наиболее производительный вариант:

Inputmask("ip")

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


Интеграция с формами

Проверка перед отправкой

form.addEventListener("submit", function (event) {

    const valid = document
        .getElementById("ip")
        .inputmask
        .isComplete();

    if (!valid) {
        event.preventDefault();
    }

});

Использование с React

import Inputmask from "inputmask";
import { useEffect, useRef } from "react";

function App() {

    const ref = useRef(null);

    useEffect(() => {

        Inputmask("ip").mask(ref.current);

    }, []);

    return <input ref={ref} />;

}

Использование с Vue

mounted() {

    Inputmask("ip").mask(this.$refs.ip);

}
<input ref="ip">

Использование с Angular

ngAfterViewInit(): void {

    Inputmask("ip").mask(
        this.ipInput.nativeElement
    );

}

Типичные ошибки

Использование простой маски вместо alias

Ошибка:

Inputmask("999.999.999.999")

Проблема:

999.999.999.999

считается валидным.


Чрезмерно сложный regex

Огромные выражения:

^((([0-9A-Fa-f]{1,4}:){7}...

могут:

  • замедлять ввод;
  • ухудшать UX;
  • вызывать ошибки курсора.

Отсутствие серверной проверки

Inputmask — клиентский инструмент.

Он:

  • помогает вводу;
  • улучшает UX;
  • ограничивает формат.

Но окончательная проверка IP должна выполняться на сервере.


Практический пример

<form id="networkForm">

    <input id="ip">

    <button type="submit">
        Сохранить
    </button>

</form>
Inputmask("ip", {
    clearIncomplete: true
}).mask("#ip");

document
    .getElementById("networkForm")
    .addEventListener("submit", function (event) {

        const input = document.getElementById("ip");

        if (!input.inputmask.isComplete()) {

            event.preventDefault();

            alert("Некорректный IP");

        }

    });