mizdra's blog

ぽよぐらみんぐ

【URI構文】URIの使用可能な文字

こんにちは、mizdraです。
今回はURIでどんな文字が使えるのか、使えないのかを見ていこうかと思います。


URIってそもそも何? URLじゃないの?

以下参照。

URIとURLの違いとは? – SummerWind

今回はRFC3986に限定して、URLの例を交えて話を進めていきます。
以降、[構文], [例]はRFC3986(2005年, 日本語)を引用しています。


 ftp://ftp.is.co.za/rfc/rfc1808.txt

 http://www.ietf.org/rfc/rfc2396.txt

 ldap://[2001:db8::7]/c=GB?objectClass?one

 mailto:John.Doe@example.com

 news:comp.infosystems.www.servers.unix

 tel:+1-816-555-1212

 telnet://192.0.2.16:80/

 urn:oasis:names:specification:docbook:dtd:xml:4.1.2

URIの構文

RFC3986(2005年, 日本語) より引用

URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
 hier-part   = "//" authority path-abempty
             / path-absolute
             / path-rootless
             / path-empty

   foo://example.com:8042/over/there?name=ferret#nose
   \_/   \______________/\_________/ \_________/ \__/
    |           |            |            |        |
 scheme     authority       path        query   fragment

foo://example.com:8042/over/there?name=ferret#nose を分解すると、

scheme: foo
authority: example.com:8042
path: /over/there
query: name=ferret
fragment: nose

このようになります。


schemeについて

構文
scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
例
http
https
ftp
mailto

使える文字

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z a b c d
e f g h i j k l m n
o p q r s t u v w x
y z
+ - .
RFC3986では、小文字のみで構成するのが望ましいとのこと。(数字や記号はわかりません)


authorityについて

構文
authority   = [ userinfo "@" ] host [ ":" port ]

userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )
host        = IP-literal / IPv4address / reg-name

IP-literal = "[" ( IPv6address / IPvFuture  ) "]"
IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

IPv6address =                            6( h16 ":" ) ls32
             /                       "::" 5( h16 ":" ) ls32
             / [               h16 ] "::" 4( h16 ":" ) ls32
             / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
             / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
             / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
             / [ *4( h16 ":" ) h16 ] "::"              ls32
             / [ *5( h16 ":" ) h16 ] "::"              h16
             / [ *6( h16 ":" ) h16 ] "::"

 ls32        = ( h16 ":" h16 ) / IPv4address
             ; アドレスの下位 32 ビット

 h16         = 1*4HEXDIG
             ; 16 進数字で表現される 16 ビットのアドレス

 IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

 dec-octet   = DIGIT                 ; 0-9
             / %x31-39 DIGIT         ; 10-99
             / "1" 2DIGIT            ; 100-199
             / "2" %x30-34 DIGIT     ; 200-249
             / "25" %x30-35          ; 250-255

 reg-name    = *( unreserved / pct-encoded / sub-delims )

 unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

 pct-encoded = "%" HEXDIG HEXDIG

 sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
             / "*" / "+" / "," / ";" / "="

 port        = *DIGIT


URI の生成を行うものや正規化を行うものは、port 要素が空の場合は、
host と port とを分けるための ":" 区切り子を省略すべきである。 
いくつかのスキームでは、userinfo や port 副構成要素を認めない。
例
//mizdra.com
//mizdra.com:60000
//mizdra@bitbucket.org
//mizdra@bitbucket.org:60000
//127.0.0.1
//0:0:0:0:0:0:0:1
//[2001:db8::7]
mizdra@mail.com

多いですね。頑張って理解してみて下さい。

使える文字

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z a b c d
e f g h i j k l m n
o p q r s t u v w x
y z
! $ % & ' ( ) * + ,
- . : ; = @ [ ] _ ~


pathについて

構文
 path          = path-abempty    ; "/" で始まるか、空
               / path-absolute   ; "/" で始まるが、"//" では始まらない
               / path-noscheme   ; コロンの無い segment で始まる
               / path-rootless   ; segment で始まる
               / path-empty      ; 文字が無い

 path-abempty  = *( "/" segment )
 path-absolute = "/" [ segment-nz *( "/" segment ) ]
 path-noscheme = segment-nz-nc *( "/" segment )
 path-rootless = segment-nz *( "/" segment )
 path-empty    = 0<pchar>

 segment       = *pchar
 segment-nz    = 1*pchar
 segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
               ; non-zero-length segment without any colon ":"

 pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
例
なし
/
/foo.bar.htm/index.html
/mizdra@mail.com(mail_address)/////

使える文字

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z a b c d
e f g h i j k l m n
o p q r s t u v w x
y z
! $ % ' ( ) * + , -
. / : ; = @ _ ~


queryについて

構文
 query       = *( pchar / "/" / "?" )
例
key=value
key1=value1&key2=value2
key1=?&key2=???&key3=/&key4=///&key5=/?/?
file=path/index.html?key=value

使える文字

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z a b c d
e f g h i j k l m n
o p q r s t u v w x
y z
! $ % ' ( ) * + , -
. / ; = ? _ ~


fragmentについて

構文(queryと同じ)
 fragment    = *( pchar / "/" / "?" )
例
top
key=value
key1=value1&key2=value2
key1=?&key2=???&key3=/&key4=///&key5=/?/?
file=path/index.html?key=value

使える文字

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
K L M N O P Q R S T
U V W X Y Z a b c d
e f g h i j k l m n
o p q r s t u v w x
y z
! $ % ' ( ) * + , -
. / ; = ? _ ~


もう一度例を貼ってみる(構文上可能なもの)

http://mizdra@bitbucket.org:60000/foo.bar.htm/index.html?file=path/jquery.jsl?&key=value#top?key=value
scheme: http
authority: //mizdra@bitbucket.org:60000
path: /foo.bar.htm/index.html
query: file=path/jquery.jsl?&key=value
fragment: top?key=value

JavaScriptURI構文解析ライブラリ

知りません。あったら教えて下さい。
上の例のファイル拡張子[html]を取得したい...

あった。
JavaScriptでURIをパースする parseuri.jsJavaScriptプログラムメモ|プログラムメモ
拡張子までは取得できないけど、代わりにファイル名が取得できるからそこからいけそう。


参考にしたサイト


URIに使ってよい文字の話 - RFC2396 と RFC3986 - 本当は怖い情報科学


最後に

これを調べるのに5時間くらい掛かりました。
(ちなみにこれを書き終えたのは大晦日の23:30くらいです)
私の時間を返して下さい(泣)

おわり