メメメモモ

プログラミング、筋トレ、ゲーム、etc

正規表現でURLをマッチさせる場合、エンコードする

以下のような感じで、エンコードしないとマッチしない。

use strict;
use warnings;
use utf8;
use Encode;

binmode STDOUT, ":utf8";

my $text = "テストhttp://example.com/テスト";

my $regex = q{\b(?:https?|shttp)://(?:(?:[-_.!~*'()a-zA-Z0-9;:&=+$,]|%[0-9A-Fa-f} .
q{][0-9A-Fa-f])*@)?(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.)} .
q{*[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?\.?|[0-9]+\.[0-9]+\.[0-9]+\.} .
q{[0-9]+)(?::[0-9]*)?(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f]} .
q{[0-9A-Fa-f])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-} .
q{Fa-f])*)*(?:/(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f} .
q{])*(?:;(?:[-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)} .
q{*)?(?:\?(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])} .
q{*)?(?:#(?:[-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*} .
q{)?};


# マッチしない                                                                                                           
if ($text =~ /($regex)/) {
    print "マッチしない\n";
}

# マッチする                                                                                                             
$text = encode_utf8($text);
if ($text =~ /($regex)/) {
    print $1 . "\n";
    print "マッチする\n";
}


とか、書いているうちにRegexp::Commonの存在を思い出した。
これを使えば普通にマッチした。

use strict;
use warnings;
use utf8;
use Regexp::Common qw/URI/;

binmode STDOUT, ":utf8";

my $text = 'テストhttp://example.com/テスト';

if ($text =~ /($RE{URI}{HTTP})/) {
    print "マッチする" . "\n";
}