Что касается IP-адресов, похоже, что есть некоторые споры о том, включать ли ведущие нули. Когда-то это было обычной практикой и общепринятым, поэтому я бы сказал, что они должны помечаться как действительные независимо от текущего предпочтения. Существует также некоторая двусмысленность в отношении того, должен ли текст до и после строки проверяться, и, опять же, я думаю, что так и должно быть. 1.2.3.4 является действительным IP, но 1.2.3.4.5 - нет, и ни часть 1.2.3.4, ни часть 2.3.4.5 не должны приводить к совпадению. Некоторые из проблем могут быть решены с помощью этого выражения:
grep -E '(^|[^[:alnum:]+)(([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])([^[:alnum:]]|$)'
Прискорбной частью здесь является тот факт, что часть регулярного выражения, которая проверяет октет, повторяется, как и во многих предлагаемых решениях. Хотя это лучше, чем для экземпляров шаблона, повторение можно полностью исключить, если в используемом регулярном выражении поддерживаются подпрограммы. В следующем примере эти функции включаются с помощью переключателя -P
, равного grep
, а также используют преимущества функций просмотра вперед и назад. (Я выбрал имя функции «o» для октета. Я мог бы использовать «octet» в качестве имени, но хотел быть кратким.)
grep -P '(?<![\d\w\.])(?<o>([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(\.\g<o>){3}(?![\d\w\.])'
Обработка точки может фактически создать ложные отрицания, если IP-адреса находятся в файле с текстом в виде предложений, поскольку точка может следовать, не будучи частью пунктирной записи. Вариант вышеупомянутого исправит это:
grep -P '(?<![\d\w\.])(?<x>([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(\.\g<x>){3}(?!([\d\w]|\.\d))'