Помогите мне написать регулярное выражение, которое выбирает строки, начинающиеся с 192 и заканчивающиеся 2 или 002?
Я хочу получить список IP-адресов, они могут состоять из 192.168.001.002 , 192.168.001.2 , 192.168.1.002 или 192.168.1.2 видов, но я хочу выбирать только в соответствии с моим правилом.

Я сделал это так:

(\d{3}\.)(\d{3}\.)(\d{1,3}\.)(\d{1,3})

но как найти строки, которые начинаются и заканчиваются определенными цифрами?

Обновить

(\d{3}\.)(\d{3}\.)(\d{1,3}\.)([02]{1,3})

Работает хорошо, но выбирает ненужную строку 192.168.027.021

2 ответа2

1

Если вы хотите, чтобы IP начинался с 192 , добавьте его в начале регулярного выражения:

192\.\d{3}\.\d{1,3}\.[02]{1,3}

Вы хотите, чтобы он заканчивался на 002 или 2 , используйте:

192\.\d{3}\.\d{1,3}\.(00)?2

где (00)? означает необязательные два нуля.

1

Резюмируя и уточняя вопрос и цели:

  • Цель: получить список IP-адресов, которые начинаются с 192 и заканчиваются 2 или 002
  • Состоит из: 192.168.001.002 , 192.168.001.2 , 192.168.1.002 или 192.168.1.2
  • Попытка: (\d{3}\.)(\d{3}\.)(\d{1,3}\.)(\d{1,3})
  • Обновлено: (\d{3}\.)(\d{3}\.)(\d{1,3}\.)([02]{1,3}) - работает, но выбирает ненужную строку 192.168.027.021

Вероятно, что вы хотите:

  • grep -P "\b\d{3}\.\d{3}\.\d{1,3}\.[02]{1,3}\b" ip.txt
  • Select-String "\b\d{3}\.\d{3}\.\d{1,3}\.[02]{1,3}\b" ip.txt
  • (Get-Content ip.txt) -match -match "\b\d{3}\.\d{3}\.\d{1,3}\.[02]{1,3}\b"

Если вы действительно хотите просто «192» в качестве первого октета, то сделайте это буквальным:

Select-String "\b192\.\d{3}\.\d{1,3}\.[02]{1,3}\b" ip.txt

Если вы просто хотите, чтобы IP-шаблоны заканчивались только 0 или 2 в последнем октете, они тоже будут работать (3 шаблона одинаковы):

  • grep -P "\b(\d{1,3}\.){3}[02]{1,3}\b" ip.txt
  • Select-String "\b(\d{1,3}\.){3}[02]{1,3}\b" ip.txt
  • (Get-Content ip.txt) -match -match "\b(\d{1,3}\.){3}[02]{1,3}\b"

От одной до трех цифр, а затем . , три раза, затем 1-3 0 или 2 символа, с разрывом слова до и после.

Это зависит от того, какой инструмент Regex вы используете, но я протестирую с grep -P (PCRE/perl-совместимым) или PowerShell/.Net, который очень похож.

Ваше первое регулярное выражение: (\d{3}\.)(\d{3}\.)(\d{1,3}\.)(\d{1,3}) говорит:

  1. Найдите 3 цифры и литерал . (Точка)
  2. Далее следуют: 3 цифры и буквальное . (Точка)
  3. Далее следуют: от 1 до 3 цифр и буквальный . (Точка)
  4. Далее следуют: от 1 до 3 цифр

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

В нем ничего не говорится о том, что это должно быть «в начале или в конце строки / строки - вероятно, хорошо, но если они встроены в текст, это может быть неверным предположением».

Ваша вторая попытка (\d{3}\.)(\d{3}\.)(\d{1,3}\.)([02]{1,3}) аналогична, за исключением 4-й части ([02]{1,3}) что говорит:

  • Найдите 0 или 2 одного до трех раз.

... так что да, он будет совпадать, когда конец равен 021 - это 02 и им нечего сказать "должен быть в конце или в строке, или следующий символ не может быть цифрой (это не 0 или 2).

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

Простейшим и, пожалуй, самым общим является bhe-якорь "разрыв слова": \b

Это утверждение нулевой ширины (не соответствует ни одному действительному символу, но утверждает / требует, чтобы что-то было истинным, переход от «словесных символов» к несловесным символам.)

  • Ваш: grep -P "(\d{3}\.)(\d{3}\.)(\d{1,3}\.)([02]{1,3})\b" ip.txt
  • Исправлено: grep -P "\d{3}\.\d{3}\.\d{1,3}\.[02]{1,3}\b" ip.txt
  • Упрощенно: grep -P "\b\d{3}\.\d{3}\.\d{1,3}\.[02]{1,3}\b" ip.txt

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .