すいません、perl で URL の表記を区切って使用したいのですが、
正規表現の理解が浅く、まだ上手くできません。
存在しないサービスや、表記の規則違反はあとで考えるとして、
どのようなパターンで取り出せば良いものでしょうか。

my $rule = '([a-z]+)://([^:/@]*):?([^@:/]*)@?([\d\w._\-]*):?(\d*)([\d\w._/\-]*)\??([\w\d%=+&]*)';
my $url = 'http://user:pass@host.net:21/path/?key=value&query';
my ($service, $user, $pass, $host, $port, $path, $query) = $url =~ m/$rule/;

このままですと http://host.net/path/ のような user@pass が
全く省かれた場合に、前に詰まってしまいました。
読み難い上に無駄な指定も多いのですが、何方かご教授願えませんか?