$search = "#^((?#
the scheme:
)(?:https?://)(?#
second level domains and beyond:
)(?:[\S]+\.)+((?#
top level domains:
)MUSEUM|TRAVEL|AERO|ARPA|ASIA|EDU|GOV|MIL|MOBI|(?#
)COOP|INFO|NAME|BIZ|CAT|COM|INT|JOBS|NET|ORG|PRO|TEL|(?#
)A[CDEFGILMNOQRSTUWXZ]|B[ABDEFGHIJLMNORSTVWYZ]|(?#
)C[ACDFGHIKLMNORUVXYZ]|D[EJKMOZ]|(?#
)E[CEGHRSTU]|F[IJKMOR]|G[ABDEFGHILMNPQRSTUWY]|(?#
)H[KMNRTU]|I[DELMNOQRST]|J[EMOP]|(?#
)K[EGHIMNPRWYZ]|L[ABCIKRSTUVY]|M[ACDEFGHKLMNOPQRSTUVWXYZ]|(?#
)N[ACEFGILOPRUZ]|OM|P[AEFGHKLMNRSTWY]|QA|R[EOSUW]|(?#
)S[ABCDEGHIJKLMNORTUVYZ]|T[CDFGHJKLMNOPRTVWZ]|(?#
)U[AGKMSYZ]|V[ACEGINU]|W[FS]|Y[ETU]|Z[AMW])(?#
the path, can be there or not:
)(/[a-z0-9\._/~%\-\+&\#\?!=\(\)@]*)?)$#i";
Просто немного почистил. Это будет соответствовать только адресам HTTP (s), и, если вы правильно скопировали все домены верхнего уровня из IANA, только те, которые стандартизированы (это будет не соответствовать http://localhost
) и с заявленным http://
.
Наконец, вы должны завершить часть пути, которая всегда будет начинаться с /, если она там есть.
Тем не менее, я бы предложил следовать за Серебром: если вы не уверены в этом, учите регулярные выражения более мягким способом и используйте проверенные шаблоны для сложных задач.
Приветствия
Кстати: Ваше регулярное выражение также будет соответствовать something.r
и something.h
(между | TO | и | TR | в вашем примере). Я оставил их в своей версии, так как, думаю, это была опечатка.
При перечитывании вопроса: Изменение
)(?:https?://)(?#
до
)(?:https?://)?(?#
(дополнительно ?
) для сопоставления URL-адресов без схемы.