RFC 2396の付録Bには、URIを解析するための正規表現が記載されています。
B.正規表現を使用したURI参照の解析
セクション4.3で説明したように、一般的なURI構文は、一部の形式のURIのコンポーネントを明確にするのに十分ではありません。このセクションで説明する「欲張りアルゴリズム」は、POSIX正規表現で使用される曖昧さ回避方法と同じであるため、URI参照の潜在的な4つのコンポーネントとフラグメント識別子を解析するために正規表現を使用するのは自然で一般的です。
次の行は、URI参照をそのコンポーネントに分解するための正規表現です。
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
12 3 4 5 6 7 8 9
上記の2行目の数字は、読みやすくするためだけのものです。それらは、各部分式の参照点を示します(つまり、各ペアの括弧)。部分式nに一致する値を。と呼びます$<n>
。たとえば、上記の式をに一致させる
http://www.ics.uci.edu/pub/ietf/uri/#Related
結果として、次の部分式が一致します。
$1 = http:
$2 = http
$3 = //www.ics.uci.edu
$4 = www.ics.uci.edu
$5 = /pub/ietf/uri/
$6 = <undefined>
$7 = <undefined>
$8 = #Related
$9 = Related
ここで<undefined>
、は、上記の例のクエリコンポーネントの場合のように、コンポーネントが存在しないことを示します。したがって、4つのコンポーネントとフラグメントの値を次のように決定できます。
scheme = $2
authority = $4
path = $5
query = $7
fragment = $9
そして、反対方向に進むと、セクション5.2のステップ7のアルゴリズムを使用して、そのコンポーネントからURI参照を再作成できます。
正規表現は、Perlで直接使用できます。
if ($uri =~ m!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!) {
my($host,$path) = ($4,$5);
print "$host => $path\n";
}
正規表現の数量詞に貪欲になると、このパターンを使用するのが難しくなる可能性があります。これs///
は、可能な限り多くのテキストを消費し、マークされていないURI境界を超えてしまう可能性があるためです。
より直接的に適用できるのは、CPANで利用可能なURI::Findモジュールです。左と右の外接は簡単です
#! /usr/bin/env perl
use strict;
use warnings;
use URI::Find;
my $finder = URI::Find->new(sub {
my(undef,$found) = @_;
"LEFT $found RIGHT";
});
while (<>) {
$finder->find(\$_);
print;
}
出力:
$猫の入力
これは、に適したプレーンテキスト入力です。
http://stackoverflow.comの質問への回答
特に、質問はで利用可能です
http://stackoverflow.com/q/15233535/123109とその答え
http://stackoverflow.com/a/15234378/123109で
$ ./mark-uris input
これは、に適したプレーンテキスト入力です。
左http://stackoverflow.com右の質問への回答
特に、質問はで利用可能です
左http://stackoverflow.com/q/15233535/123109右と答え
左http://stackoverflow.com/a/15234378/123109右