RFC3986
Internet Engineering Task Force ( IETF ) の Request for Comments (RFC) 文書番号 3986 というタイトルの「Uniform Resource Identifier (URI): Generic Syntax」 ( RFC3986 ) は、信頼できる標準であり、アプリケーションを構成するすべてのコンポーネントの正確な構文を記述しています。有効なジェネリック URI (Uniform Resource Identifier)。付録 Bは、必要な正規表現を示しています。
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
この正規表現では、URI 部分は次のように格納されます。
scheme = $2
authority = $4
path = $5
query = $7
fragment = $9
上記の正規表現を文書化する目的で、コメントとインデントを使用して自由にスペースを空けるモードで書き直し、指定されたすべての主要部分を解析するテスト済みの PHP スクリプトの形式でここに示します。 URI 文字列:
PHP ソリューション:
<?php // test.php Rev:20130830_0800
$re_rfc3986_parse_generic_uri = '%
# Parse generic URI according to RFC3986 Appendix B.
^ # Anchor to start of string.
(?: # Group for optional scheme.
([^:/?#]+) # $1: Uri SCHEME.
: # Scheme ends with ":".
)? # Scheme is optional.
(?: # Group for optional authority.
// # Authority starts with "//"
([^/?#]*) # $2: Uri AUTHORITY.
)? # Authority is optional.
([^?#]*) # $3: Uri PATH (required).
(?: # Group for optional query.
\? # Query starts with "?".
([^#]*) # $4: Uri QUERY.
)? # Query is optional.
(?: # Group for optional fragment.
\# # Fragment starts with "#".
(.*) # $5: Uri FRAGMENT.
)? # Fragment is optional.
$ # Anchor to end of string.
%x';
$text = "http://www.site.com/part1/part2?key=value#blub";
if (preg_match($re_rfc3986_parse_generic_uri, $text, $matches)) {
print_r($matches);
} else {
echo("String is not a valid URI");
}
?>
元の正規表現に対して 2 つの機能上の変更が行われました。1.) 不要なキャプチャ グループが非キャプチャに変換され、2.)$
文字列アンカーの終わりが式の最後に追加されました。番号付きのキャプチャ グループを使用するのではなく、名前付きのキャプチャ グループを使用することで、さらに読みやすいバージョンを作成できますが、JavaScript 構文に直接移行することはできないことに注意してください。
PHP スクリプト出力:
Array
(
[0] => http://www.site.com/part1/part2?key=value#blub
[1] => http
[2] => www.site.com
[3] => /part1/part2
[4] => key=value
[5] => blub
)
JavaScript ソリューション:
以下は、有効な URI をさまざまなコンポーネントに分解する、テスト済みの JavaScript 関数です。
// Parse a valid URI into its various parts per RFC3986.
function parseValidURI(text) {
var uri_parts;
var re_rfc3986_parse_generic_uri =
/^(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?$/;
// Use String.replace() with callback function to parse the URI.
text.replace(re_rfc3986_parse_generic_uri,
function(m0,m1,m2,m3,m4,m5) {
uri_parts = {
scheme : m1,
authority : m2,
path : m3,
query : m4,
fragment : m5
};
return; // return value is not used.
});
return uri_parts;
}
返されたオブジェクトの非パス プロパティはundefined
、URI 文字列に存在しない場合があることに注意してください。また、URI 文字列がこの正規表現と一致しない場合 (つまり、明らかに無効である場合)、返される値はundefined
です。
ノート:
- 必要なジェネリック URI の唯一のコンポーネントはパスです(パス自体は空である場合があります)。
- 空の文字列は有効な URI です。
- 上記の正規表現は URI を検証しませんが、指定された有効な URI を解析します。
- 上記の正規表現が URI 文字列と一致しない場合、その文字列は有効な URI ではありません。ただし、その逆は当てはまりません。文字列が上記の正規表現に一致する場合、URI が有効であることを意味するのではなく、URI として解析可能であることを意味するだけです。
URI を検証し、さらに分解することに興味がある人のために、RFC3986 の付録 A で定義されているすべての部分を取り上げ、それらを正規表現構文に変換する記事を書きました。見る:
ハッピー正規表現!