teddy, постараюсь пояснить. Да кстати, я там обновил свой ответ, последнего символа $ нет теперь, но это не принципиально, разницы никакой, просто дублирование получалось.
Теперь по порядку.
Символы ^ и $ - это начало и конец строки соответственно. Где бы они ни были, хоть в символьно классе (в квадратных скобках), хоть еще где. Если нет экранирования - это спец символы. Также как и точка, ну вы с ней уже разобрались
Есть только одно исключение для символа ^, когда он не значит "начало строки", но пока опустим этот момент.
Комбинация ?: - это группировка без обратной связи. Ставится сразу после открывающейся круглой скобки. Используется если нам не нужно нигде использовать часть заключенную в этой скобке. Т.е. если идет просто группировка (просто круглые скобки), то значение, что в них попадет будет запомнено и доступно после. Это как вы проверяли части IP в своем варинте в цикле. Т.е. у вас после preg_match был массив с частями исходной строки. А вот если указать ?:, то этих частей уже не будет. Надеюсь ясно объянил. Зачем это нужно? Не занимает память, соответственно ускорение работы. С регулярками это вобще критично, т.к. они сами по себе достаточно медленные.
"
волшебная палочка |" означает "или". Т.е. в моем случае выражение (?:\.|$) значит следующее: символ точка или конец стоки.
Чтоб еще понятней стало опишу, как я составлял эту регулярку по шагам.
1. Вся строка это ip адресс, т.е. от начала до конца. ок, пишем
2. Строка состоит строго из четырех
частей (четыре части разделеных точкой). ок, пишем дальше