どの文字がURLを無効にしますか?
これらは有効なURLですか?
example.com/file[/].html
http://example.com/file[/].html
どの文字がURLを無効にしますか?
これらは有効なURLですか?
example.com/file[/].html
http://example.com/file[/].html
回答:
一般に、RFC 3986で定義されている URI (セクション2:文字を参照)には、次の84文字のいずれかを含めることができます。
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
このリストには、URI内のこれらの文字が出現する可能性のある場所が記載されていないことに注意してください。
その他の文字は、パーセントエンコーディング(%
hh
)でエンコードする必要があります。URIの各部分には、パーセントエンコードされた単語で表す必要のある文字について、さらに制限があります。
/^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/
ているはずです: あなたがそれが受け入れるべきだったと思った何か他に何かありましたか?(正確に言うと、正規表現は文字列に有効なURL文字が含まれているかどうかをチェックするだけで、文字列が整形式のURLを含んでいるかどうかをチェックしません。)
いくつかの明確化を追加し、上記の質問に直接対処するために、URLとURIに問題を引き起こすいくつかのクラスの文字があります。
許可されていないためにURL / URIに表示されないはずの文字、予約文字(下記で説明)、および場合によっては問題を引き起こす可能性があるが、「賢明でない」または「安全でない」とマークされている文字があります。文字が制限されている理由の説明は、RFC-1738(URL)およびRFC-2396(URI)に明確に記載されています。新しいRFC-3986(RFC-1738への更新)は、特定のコンテキストで許可される文字の構成を定義していますが、古い仕様では、次のルールで許可されない文字のより簡単で一般的な説明を提供しています。
除外されたUS-ASCII文字は、URI構文内で許可されていません。
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
文字「#」は、フラグメント識別子からURIを区切るために使用されるため、除外されます。パーセント文字「%」は、エスケープ文字のエンコードに使用されるため除外されています。つまり、「#」と「%」は、特定のコンテキストで使用する必要がある予約文字です。
賢くない文字のリストは許可されますが、問題を引き起こす可能性があります:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
クエリコンポーネント内で予約されている文字、および/またはURI / URL内で特別な意味を持つ文字:
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
上記の「予約済み」構文クラスは、URI内では許可されているが、汎用URI構文の特定のコンポーネント内では許可されていない可能性がある文字を指します。「予約済み」セットの文字は、すべてのコンテキストで予約されているわけではありません。たとえば、ホスト名にはオプションのユーザー名を含めることができるためftp://user@hostname/
、「@」文字が特別な意味を持っているようなものにすることができます。
以下は、無効で無意味な文字( '$'、 '['、 ']'など)があり、適切にエンコードする必要があるURLの例です。
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
URI / URLの文字制限の一部は、プログラミング言語に依存しています。たとえば、 '|' (0x7C)文字は、URI仕様で「unwise」とマークされているだけですが、Java java.net.URIコンストラクターでURISyntaxExceptionをスローします。そのため、URLなどhttp://api.google.com/q?exp=a|b
は許可されずhttp://api.google.com/q?exp=a%7Cb
、URIオブジェクトインスタンスでJavaを使用する場合と同様にエンコードする必要があります。
?
はリテラルは問題ありませんが、それ以前は不可能であり、これらのリストに属していないと思います。ああ、そして最後の文字列の代わりに、という意味ですか?@
%25
%7C
ここにある既存の回答のほとんどは、実際のアドレスの使用を完全に無視しているため、実用的ではありません。
最初に、用語への脱線。これらのアドレスは何ですか?それらは有効なURLですか?
歴史的には、答えは「ノー」でした。RFC 3986によれば、2005年以降、そのようなアドレスはURIではありません(URL はURIの一種であるため、URLではありません)。2005 IETF標準の用語に従って、RFC 3987で定義されているように、それらをIRI(Internationalized Resource Identifiers)と適切に呼ぶ必要があります。これらは技術的にはURIではなく、IRI内のすべての非ASCII文字をパーセントエンコードするだけでURIに変換できます。 。
現代の仕様では、答えは「はい」です。WHATWG生活水準は、単に以前に「URLの」として「のURI」または「虹彩」と呼ばれることになるすべてのものを分類します。これにより、仕様の専門用語を、仕様をまだ読んでいない一般の人々が、仕様の目標の 1つである「URL」という言葉をどのように使用するかと一致させます。
「URL」のこの新しい意味によれば、どの文字が許可されますか?そのようなクエリ文字列やパスなどのURLの多くの部分では、我々は、任意の使用を許可している「URL単位」です、
「URLコードポイント」とは?
URLコードポイントのASCII英数字、U + 0021(!)され、U + 0024($)、U + 0026(&)、U + 0027( ')、U + 0028左括弧、U + 0029右括弧、U + 002A(*)、U + 002B(+)、U + 002C(、)、U + 002D(-)、U + 002E(。)、U + 002F(/)、U + 003A(:)、U + 003B (;)、U + 003D(=)、U + 003F(?)、U + 0040(@)、U + 005F(_)、U + 007E(〜)、およびU + 00A0からUの範囲のコードポイント+ 10FFFD(サロゲートと非文字を除く)。
(注「URLのコードポイント」のリストには含まれていないこと%
ということが、%
パーセントをコードする配列を、彼らがしている部分ならばsは、「URLのコード単位」で許可されています。)
このセットにない文字の使用が仕様で許可されている唯一の場所は、IPv6アドレスがandで囲まれているhostです。URLの他のすべての場所で、URLユニットを許可するか、さらに限定的な文字セットを許可します。[
]
歴史のために、そしてここでの回答では他の場所では十分に検討されていないので、古い仕様のペアで許可されていたものを調べてみましょう。
まず、2種類のRFC 3986 予約文字があります。
:/?#[]@
、これはRFC 3986で定義されたURIの一般的な構文の一部です!$&'()*+,;=
、これはRFCの一般的な構文の一部ではありませんが、特定のURIスキームの構文コンポーネントとして使用するために予約されています。例えば、セミコロンとコンマは構文の一部として使用されているデータのURIと、&
及び=
ユビキタスの一部として使用される?foo=bar&qux=baz
(クエリ文字列にフォーマットされていない RFC 3986で指定されました)。上記の予約文字はすべて、エンコードなしのURIで合法的に使用できます。これは、構文上の目的に使用するか、そのような使用が構文上の目的に使用される文字と誤解されない場所でデータ内のリテラル文字として使用できます。(たとえば/
、URLには構文上の意味がありますが、クエリ文字列には意味がないため、クエリ文字列ではエンコードせずに使用できます。)
RFC 3986はまた、いくつかの指定予約されていない、常にエンコードせずにデータを表現するために、単純に使用できる文字を、:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
最後に、%
文字自体はパーセントエンコーディングが許可されています。
葉のみ、以下のASCII文字という禁断の URLに表示されてから:
"<>\^`{|}
ASCIIの他のすべての文字は、URLで合法的に機能できます。
次に、RFC 3987は、予約されていない文字のセットを次のUnicode文字範囲で拡張します。
%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD
古い仕様からのこれらのブロックの選択は、最新のUnicode ブロック定義を考えると、奇妙で恣意的なようです。これはおそらく、RFC 3987が作成されてから10年でブロックが追加されたためです。
最後に、URLに合法的に表示できる文字を知るだけでは、特定の文字列が合法的なURLであるかどうかを認識するだけでは十分ではないことに注意してください。たとえば、予約文字[
と]
は、http:// [1080 :: 8:800:200C:417A] / fooのようなURLのIPv6リテラルホストの一部としては有効ですが、他のコンテキストでは無効です。 OPの例http://example.com/file[/].html
は違法です。
補足的な質問www.example.com/file[/].html
で、有効なURL かどうかを尋ねました。
URLはURIの一種であり、有効なURIにはhttp:
(RFC 3986を参照)のようなスキームが必要であるため、そのURLは無効です。
http://www.example.com/file[/].html
が有効なURL かどうかを確認するつもりなら、角かっこ文字は有効ではないため、答えはまだノーです。
角かっこ文字は、次の形式のURL用に予約されていますhttp://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(ホスト名ではなくIPv6リテラル)。
問題を完全に理解したい場合は、RFC 3986を注意深く読む価値があります。
[
そして]
、私が見てきたほとんどのパーサーのための有効なURIではありません。これは実際に現実の世界で私をねじ込みました:stackoverflow.com/questions/11038967/...
Unwise
URIに対して非常に真剣に取り組んでいますが、URLライブラリでは問題ありません。つまり、無視するフラグはありませんUnwise
。URLについて、Rustのlangを確認する必要があります(ブラウザー用に構築されているため、何をするか知りたいです)。ただし、ほとんどのブラウザは「[」、「]」も問題なく通過します。したがって、理論的にはC / C ++で言ったように、それらはサブ/スーパーですが、現実はそれほど正確ではありません。スーパー/サブセットの仕様とセマンティクスの解釈に大きく依存します。
URI(URLはURIの一種です)で使用できるすべての有効な文字は、RFC 3986で定義されています。
他のすべての文字は、最初に「URLエンコード」されていれば、URLで使用できます。これには、特定の「コード」の無効な文字の変更が含まれます(通常、パーセント記号(%)の後に16進数が続く形式です)。
このHTML HTMLエンコーディングリファレンスリンクには、無効な文字のエンコーディングのリストが含まれています。
いくつかのUnicode文字範囲は有効なHTML5ですが、それらを使用することはまだお勧めできません。
たとえば、href
ドキュメントはhttp://www.w3.org/TR/html5/links.html#attr-hyperlink-hrefと言います:
aおよびarea要素のhref属性には、スペースで囲まれている可能性のある有効なURLの値が必要です。
次に、「有効なURL」の定義はhttp://url.spec.whatwg.org/を指し、次のことを目的としています。
RFC 3986とRFC 3987を最新の実装に合わせて、プロセスで廃止します。
このドキュメントでは、URLコードポイントを次のように定義しています。
ASCII英数字、「!」、「$」、「&」、「 '」、「(」、「)」、「*」、「+」、「、」、「-」、「。」、「/」 、「:」、「;」、「=」、「?」、「@」、「_」、「〜」、およびU + 00A0〜U + D7FF、U + E000〜U + FDCFの範囲のコードポイント、U + FDF0〜U + FFFD、U + 10000〜U + 1FFFD、U + 20000〜U + 2FFFD、U + 30000〜U + 3FFFD、U + 40000〜U + 4FFFD、U + 50000〜U + 5FFFD、U +60000からU + 6FFFD、U + 70000からU + 7FFFD、U + 80000からU + 8FFFD、U + 90000からU + 9FFFD、U + A0000からU + AFFFD、U + B0000からU + BFFFD、U + C0000 U + CFFFD、U + D0000からU + DFFFD、U + E1000からU + EFFFD、U + F0000からU + FFFFD、U + 100000からU + 10FFFD。
次に、「URLコードポイント」という用語がステートメントで使用されます。
cがURLコードポイントではなく、「%」でもない場合、解析エラー。
スキーマ、権限、相対パス、クエリ、フラグメントの状態など、解析アルゴリズムのいくつかの部分で:基本的にURL全体です。
また、バリデータhttp://validator.w3.org/はのような"你好"
URLに対してはパスし、スペースのような文字を含むURLに対してはパスしません"a b"
もちろん、Stephen Cが述べたように、それは文字だけでなくコンテキストについてもです。アルゴリズム全体を理解する必要があります。ただし、クラスの「URLコードポイント」はアルゴリズムの重要なポイントで使用されるため、何を使用できるか、または使用できないかについての良いアイデアが得られます。
文字列でURLを分割する文字を選択する必要があるので、URLで自分で見つけることができない文字のリストを作成することにしました。
>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'
したがって、可能な選択肢は、改行、タブ、スペース、バックスラッシュ、および"<>{}^|
です。私はスペースか改行で行くと思います。:)
本当にあなたの質問への答えではありませんが、URLの検証は本当に深刻なピタですドメイン名を検証し、URLのクエリ部分を残す方が良いでしょう。それが私の経験です。また、URLにpingを送信して有効な応答が得られるかどうかを確認することもできますが、そのような単純なタスクには多すぎる可能性があります。
URLを検出するための正規表現は豊富ですが、それをググってください:)
古いhttp(0.9、1.0、1.1)リクエストとレスポンスのリーダー/ライターを実装しています。リクエストURIは最も問題の多い場所です。
RFC 1738、2396、または3986をそのまま使用することはできません。より多くの文字を許可する多くの古いHTTPクライアントとサーバーがあります。そこで、誤って公開されたウェブサーバーアクセスログに基づいて調査を行いました"GET URI HTTP/1.0" 200
。
以下の非標準文字がURIでよく使用されることがわかりました。
\ { } < > | ` ^ "
これらの文字は、RFC 1738で安全でないと説明されています。
すべての古いHTTPクライアントおよびサーバーと互換性を持たせる場合は、リクエストURIでこれらの文字を許可する必要があります。
この研究の詳細については、http-ogをご覧ください。
テキストのURLをアンカータグに変換するPHPの正規表現をいくつか思いつきました。(最初にすべてのwww。urlをhttp://に変換し、次にhttps?://を含むすべてのURLをhref = ... htmlリンクに変換します
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>',
preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string)
);