Регулярное выражение — не соответствует концу строки для IOC IP|PORT

Я пытаюсь создать выражение регулярного выражения, которое соответствует чему-то, что не отформатировано как: ip|port.
Значение порта может быть между [1, 65535].

Примеры набора данных:
(1) 8.8.8.8|0 (плохо: порт 0 не разрешен)
(2) 8.8.8.8|1 (хорошо)
( 3) 8.8.8.8|65536 (плохо: порт > 65535)
(4) 8.8.8.8|dawda (плохо: char)

Выражение регулярного выражения (соответствие неверным данным) должно соответствовать (1), (3) и (4).

Учтите, что часть ip всегда будет правильной (нет необходимости в регулярном выражении), и что мне нужно проверить, так это порт. Из-за этого я начал оценку с конца строки следующим образом:

Регулярное выражение для соответствия порту от 0 до 65535:
\|(6553[0-5]|655[0-2]\d|65[0-4]\d{2} |6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3})

Регулярное выражение с совпадением конца строки:
\ |(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{ 4}|[1-9]\d{0,3})$

Теперь я хочу отменить это, чтобы поймать строку, которая не заканчивается действительным портом. Я смотрю на другие форумы (Как отменить конкретное слово в регулярном выражении? , Регулярные выражения и отрицание целой группы символов) и изучите об отрицательном упреждающем регулярном выражении.

Согласно этим форумам и отрицательному регулярному выражению, мое регулярное выражение должно быть таким:

^(?!(MY_REGEX)).*$

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

Отрицательное регулярное выражение в конце строки:
^(?!. \|(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d {4}|[1-9]\d{0,3})).$

У меня проблема с конечной частью .*$, которая разрешает что-то после номера порта. В конце концов, этот код будет выполняться с помощью PHP. В соответствии с PHP, ретроспективное выражение переменной длины не поддерживается, что заставляет меня в первую очередь выбирать регулярное выражение с опережением.

Спасибо за помощь.


person Vincent L.    schedule 03.08.2017    source источник
comment
Я бы рекомендовал использовать простое регулярное выражение для базовой проверки синтаксиса и использовать группу захвата для числа после |. Затем в вашем коде используйте метод для проверки диапазона чисел. Regex не очень хорошо справляется с математикой.   -  person CAustin    schedule 04.08.2017


Ответы (1)


Наиболее подходящим способом является захват части после | с помощью (.*) (любые символы 0+, кроме символов разрыва строки) и проверка ее с помощью небольшого количества кода PHP:

if (preg_match('~^\d+(?:\.\d+){3}\|(.*)$~', $s, $res)) {
    if (ctype_digit($res[1]) && intval($res[1]) > 0 && intval($res[1]) < 65536 ) { // valid port, omit
        echo "The port is valid: " . $res[1];
    } else {
        echo "Invalid port: " . $res[1];
    }
}

ctype_digit проверяет, содержит ли строка только цифры.

См. онлайн-демонстрацию PHP.

Если вам просто нужен шаблон, который будет совместим с PCRE, вы можете использовать следующий шаблон:

^\d+(?:\.\d+){3}\|(?!(?:[1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$)(.*)$

См. демонстрацию регулярного выражения.

Подробнее см. ниже:

  • ^ - начало строки
  • \d+ - 1+ цифры
  • (?:\.\d+){3} — 3 последовательности ., за которыми следует 1+ цифра (шаблон IP, который не требует проверки, вы считаете его предварительно проверенным)
  • \| - буквальное |
  • (?!(?:[1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$) - a negative lookahead that will fail the match if it finds the following numeric values at the end of the string:
    • [1-9]\d{0,3} - a digit from 1 to 9 and then 0 to 3 digits (1 to 9999)
    • [1-5]\d{4} - цифра от 1 до 5 и далее 4 цифры (от 10000 до 59999)
    • 6[0-4]\d{3} - 6, цифра от 0 до 4 и затем 3 цифры (от 60000 до 64999)
    • 65[0-4]\d{2} - 65, цифра от 0 до 4 и 2 цифры (от 65000 до 65499)
    • 655[0-2]\d - 655, цифра от 0 до 2 и 1 цифра (от 65500 до 65529)
    • 6553[0-5] - 65530 to 65535.
  • (.*) - захватить часть, которая не является допустимым портом, любые символы 0+ (кроме символов разрыва строки) до конца строки
  • $ - конец строки.
person Wiktor Stribiżew    schedule 04.08.2017