Соответствие регулярному выражению, только если двоеточие найдено

Я хочу написать регулярное выражение, которое соответствует портам. Это прекрасно работает, но часто время тоже совпадает. Я хотел создать отрицательный просмотр вперед и просмотр назад, чтобы, если в строке есть другое двоеточие, оно не совпадало. Но я делаю ошибку и не могу ее заметить:

Я хочу, чтобы порты совпадали, но не совпадали по времени.

(?<!:):\d{1,5}\b(?!:)

Вот ссылка на сохраненное регулярное выражение.

Иногда порты отображаются так: 443 и :80 без информации IPv4. Вот почему я ищу решение для обхода. Я использую ECMAScript.

Какой язык вы используете?

Gilles Quénot 21.02.2023 21:26

Вам это нужно только для IPv4?

RomanPerekhrest 21.02.2023 21:36

ECMAScript, поэтому используется один javascript, да, только для IPv4. Но я забыл упомянуть, что порты иногда отображаются без IP-адресов. Мне придется отредактировать вопрос для этого.

Mario Jost 21.02.2023 21:38
: - двоеточие, ; - точка с запятой
Kirill Polishchuk 21.02.2023 23:22

Какую версию ECMAScript поддерживает разновидность регулярных выражений? Обратите внимание, что даже в реализациях JS разновидности регулярных выражений различаются (ср. Safari/Chrome).

Wiktor Stribiżew 22.02.2023 10:34

@MarioJost Я только что обновил свой ответ, который обрабатывает пустой IP-адрес, все действительные адреса IPv4 и ограничивает порты допустимыми портами. Теперь у него есть пример ESMAScript. Соответствие регулярному выражению, только если двоеточие найдено.

James Risner 22.02.2023 16:36

@WiktorStribiżew Мой обновленный ответ работает в большинстве браузеров? Кажется, это сработало для меня при тестировании основных трех.

James Risner 22.02.2023 16:37
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Интервьюер: Почему &apos;[] instanceof Object&apos; возвращает &quot;true&quot;?
Интервьюер: Почему '[] instanceof Object' возвращает "true"?
Все мы знаем, что [] instanceof Array возвращает true, но почему [] instanceof Object тоже возвращает true?
Абстрактное синтаксическое дерево (AST) и как оно работает с ReactJS
Абстрактное синтаксическое дерево (AST) и как оно работает с ReactJS
Абстрактное синтаксическое дерево (AST) - это древовидная структура данных, которая представляет структуру и иерархию исходного кода на языке...
1
7
70
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Это регулярное выражение:

¹

^\d+\.\d+\.\d+\.\d+:\K\d{1,5}

Или

²

^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}:\K\d{1,5}

Предполагая, что ip's только ipv4

¹ Online Demo ² Online Demo

Это работает для вас?

Gilles Quénot 21.02.2023 22:23

Он работает в тестере регулярных выражений, но не работает в SecureCRT, где я пытаюсь это сделать. Кажется, что он не может обработать команду /K. Но спасибо за вашу помощь.

Mario Jost 22.02.2023 13:02

Если вас интересует что-либо после одиночного : в строке:

^[^:]*:(\d{1,5})$

И используйте группу 1 для вашего порта.

Если вы хотите быть немного более строгим и ограничить диапазон портов фактическим от 0 до 65535, вы можете использовать это:

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

(для краткости ;-) я разрешил ведущие нули в этом регулярном выражении)

Ваше регулярное выражение отлично подходит в тестере. Также спасибо за проверку диапазонов портов, это приятная деталь. Но я не могу использовать группы в своем приложении, поэтому оно будет соответствовать только всей строке. Я действительно надеялся, что смогу избежать совпадения, если в строке более одной точки с запятой.

Mario Jost 21.02.2023 22:21

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

cyberbrain 21.02.2023 22:27

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

const regex = /(?:\.\d+|\B)(?::)(\d{1,5})\b(?!:)/g;

// Alternative syntax using RegExp constructor
// const regex = new RegExp('(?:\\.\\d+|\\B)(?::)(\\d{1,5})\\b(?!:)', 'g')

const str = `10.0.243.7:38518    :440
62.11.21.68:443   port  :80
01:11:22
21:15:19
:443 `;
let m;

ports = Array.from(str.matchAll(regex), (m) => m[1])
console.info(ports)
Ответ принят как подходящий

Если вы используете Javascript и можете использовать просмотр назад переменной длины, вы можете утверждать : слева, но утверждать не ., за которым следуют цифры, а затем : слева:

(?<=:)(?<!:\d+:)\d{1,5}\b(?!:)

Демонстрация регулярных выражений

const regex = /(?<=:)(?<!:\d+:)\d{1,5}\b(?!:)/g;
const s = `10.0.243.7:38518
62.11.21.68:443
01:11:22
21:15:19`;
console.info(s.match(regex));

Если вы хотите также сопоставить двоеточие:

(?<!:\d+):\d{1,5}\b(?!:)

Демонстрация регулярных выражений

const regex = /(?<!:\d+):\d{1,5}\b(?!:)/g;
const s = `10.0.243.7:38518
62.11.21.68:443
01:11:22
21:15:19`;
console.info(s.match(regex));

Это именно то, что мне нужно, большое спасибо.

Mario Jost 22.02.2023 13:07
Я хочу написать регулярное выражение, которое соответствует портам. Забыл упомянуть, что порты иногда отображаются без IP.

Регулярное выражение ECMAScript:

^((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b)){4}|):(?<port>((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-5]{0,5})|([0-9]{1,4})))$

ПКРЕ:

^((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b)){4}|):\K((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-5]{0,5})|([0-9]{1,4}))$

Это обрабатывает все случаи, включая порт, показанный без IP-адреса.

Посмотрите ECMAScript и PCRE в действии.

  • Сначала утвердите начало строки (^).
  • Затем запишите число от 0 до 9, 10–99, 100–199, 200–249 или 250–255.
  • Требуйте одну точку после числа и повторите 4 раза.
  • Граница слова (\b) не позволяет четвертому соответствовать шаблону .:.
  • Затем мы сбрасываем (\K), чтобы игнорировать IPv4-адрес в совпадении в PCRE и использовать именованный захват в ESMAScript.
  • Затем сопоставляем 0-9, 10-99, 100-999, 1000-9999, 10000-59999, 60000-64999, 65000-65499, 65500-65529, 65530-65535 для порта.
  • Наконец, мы утверждаем конец ($).

Пример Javascript:

const regex = /^((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b)){4}|):(?<port>((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-5]{0,5})|([0-9]{1,4})))$/gm;

const input = `10.0.243.7:38518
62.11.21.68:443
01:11:22
21:15:19
10.20.30.40:2312
10.20..40:2312
10.20.40.:2312
10.20.40:5312
10.20.30.40:0
10.20.30.40:0;
:293
:65536
1.1.2.2:65536`;

for (const match of input.matchAll(regex)) {
    console.info(`${match.groups.port}`);
}

Другие вопросы по теме