Проблема заключается в том, что ваше регулярное выражение не учитывает числовые адреса IPv6 (не то, что я рекомендовал бы их использовать в первую очередь, разумно использовать DNS для привязки их к имени в производственном использовании).
Чтобы проверить, как все удается, давайте немного адаптировать RE, чтобы захватить немного больше:
([^:]+)://([^:/]+)(:[0-9]+)?(/?)
В этой версии, все, что не совсем неподвижную захватывается. Теперь давайте протестируем его против ваших прецедентов с regexp -inline
(опция -inline
делает regexp
возвращает подстроки, соответствующие отличным для отладки REs, и это действительно помогает помещать RE в переменную и использовать ее, как показано ниже, легче избежать опечаток):
% set RE {([^:]+)://([^:/]+)(:[0-9]+)?(/?)}
([^:]+)://([^:/]+)(:[0-9]+)?(/?)
% regexp -inline $RE {https://10.77.56.89}
https://10.77.56.89 https 10.77.56.89 {} {}
% regexp -inline $RE {https://[2001:1:1:43::115]/ucmuser}
{https://[2001:1} https {[2001} :1 {}
Мы видим, что [^:]+
часть является проблемой, так как она останавливается на первом двоеточие IPv6-адрес. Нам нужно добавить специальный случай, когда первая часть имени хоста начинается с [
; мы не выполним полную проверку (проверьте пакет ip
в Tcllib, если вы этого хотите), но мы можем сделать некоторые простые вещи, проверив, что содержимое скобок является шестнадцатеричными цифрами или двоеточиями.
% set RE {([^:]+)://([^]:[/]+|\[[0-9a-f:A-F]+\])(:[0-9]+)?(/?)}
([^:]+)://([^]:[/]+|\[[0-9a-f:A-F]+\])(:[0-9]+)?(/?)
% regexp -inline $RE {https://10.77.56.89}
https://10.77.56.89 https 10.77.56.89 {} {}
% regexp -inline $RE {https://[2001:1:1:43::115]/ucmuser}
{https://[2001:1:1:43::115]/} https {[2001:1:1:43::115]} {}/
Это выглядит прямо ко мне (да, это занимает немного мастерить, чтобы получить синтаксис право из-за взаимодействия с синтаксисом для символьных классов POSIX РЗ). Преобразование иметь одни и те же группы перехвата, которые вы изначально были, ваш RE должен быть таким:
[^:]+://(?:[^]:[/]+|\[[0-9a-f:A-F]+\])(:[0-9]+)?/?
(NB: Мы используем, не захватывая скобку, (?:
... )
, в этом, потому что нам нужно чередование, |
между двумя суб-УЭ)
Я фанат символьных классов POSIX: мы можем заменить '[0-9a-е : AF] 'с' [[: xdigit:]:] 'для« шестнадцатеричной цифры или двоеточия » –