Regexp::Common::URI::http でURIのフラグメントがマッチしないなぁ

ステキな正規表現 $RE{URI}{HTTP} を使うと、テキストからURIをさくっと抜き出したりaタグで囲ったりできるんですが、フラグメント(aタグname属性値の#topみたいなの)にマッチしないんす。

なぜか?

URIについてのRFCにはRFC 3986があります。で、RFC 3986はRFC 2396をobsoletesしてるんで、URIについては最新の仕様が3986で、1コ前の仕様が2396ということになります。

で、RFC 2396ではURIBNFに含まれていなかったfragmentが、3986では含まれるようになったんす。

おそらく、Regexp::Common::URI::httpはRFC 2396の時代に作られたため、$RE{URI}{HTTP}がフラグメントにマッチしないんだと思います。

$RE{URI}{HTTP}{fragment=>1}でフラグメントにもマッチするようになるとステキだと思うんですが、もういいから全部フラグメントつきのURIにマッチしてもいっかという向きには↓のパッチでいけると思います。ついでに、{-keep}すると$9にマッチしたフラグメントが入るようにしてます。

--- /usr/local/share/perl/5.8.4/Regexp/Common/URI/http.pm	2004-06-10 06:42:48.000000000 +0900
+++ Regexp/Common/URI/http.pm	2006-10-21 00:53:48.000000000 +0900
@@ -7,14 +7,14 @@
 
 use Regexp::Common               qw /pattern clean no_defaults/;
 use Regexp::Common::URI          qw /register_uri/;
-use Regexp::Common::URI::RFC2396 qw /$host $port $path_segments $query/;
+use Regexp::Common::URI::RFC2396 qw /$host $port $path_segments $query $fragment/;
 
 use vars qw /$VERSION/;
 
 ($VERSION) = q $Revision: 2.101 $ =~ /[\d.]+/g;
 
 my $http_uri = "(?k:(?k:http)://(?k:$host)(?::(?k:$port))?"           .
-               "(?k:/(?k:(?k:$path_segments)(?:[?](?k:$query))?))?)";
+               "(?k:/(?k:(?k:$path_segments)(?:[?](?k:$query))?))?(?k:#$fragment)?)";
 
 register_uri HTTP => $http_uri;