URLパターン

現行標準 — 最終更新日

参加方法:
GitHub whatwg/urlpattern (新しいissue, オープン中のissue)
Matrixでチャット
コミット履歴:
GitHub whatwg/urlpattern/commits
このコミット時点のスナップショット
@urlpatterns
テスト:
web-platform-tests urlpattern/ (進行中の作業)
翻訳 (規範的でない):
简体中文
日本語
한국어

概要

URLパターン標準は、便利なパターン構文に基づいてURLをマッチングするウェブプラットフォームのプリミティブを提供します。

1. URLパターン

1.1. はじめに

URLパターンは、複数のコンポーネントから構成されており、それぞれが パターンを表し、対応するURLのコンポーネントに対してマッチングされます。

各コンポーネントごとに文字列を使用して構築したり、簡易表記文字列から構築することができます。オプションで基準URLに対して相対的に解決することもできます。

簡易表記 "https://example.com/:category/*" は、以下のコンポーネントに対応します:

protocol
"https"
username
"*"
password
"*"
hostname
"example.com"
port
""
pathname
"/:category/*"
search
"*"
hash
"*"

次のURLにマッチします:

次のURLにはマッチしません:

このパターンは比較的単純で、ほとんどのコンポーネントが正確な文字列でマッチするか、任意の文字列("*")を許容します。 pathname コンポーネントは少なくとも2つの/区切りのパスコンポーネントを持つパスにマッチし、最初のものが"category"としてキャプチャされます。

簡易表記 "http{s}?://{:subdomain.}?shop.example/products/:id([0-9]+)#reviews" は、以下のコンポーネントに対応します:

protocol
"http{s}?"
username
"*"
password
"*"
hostname
"{:subdomain.}?shop.example"
port
""
pathname
"/products/:id([0-9]+)"
search
""
hash
"reviews"

次のURLにマッチします:

次のURLにはマッチしません:

このパターンはより複雑で、以下を含みます:

簡易表記 "../admin/*" に基準URL "https://discussion.example/forum/?page=2" を使用した場合、以下のコンポーネントに対応します:

protocol
"https"
username
"*"
password
"*"
hostname
"discussion.example"
port
""
pathname
"/admin/*"
search
"*"
hash
"*"

次のURLにマッチします:

次のURLにはマッチしません:

このパターンは、パス名が基準URLに対してどのように解決されるか、つまり相対URLのような挙動を示しています。

1.2. URLPattern クラス

typedef (USVString or URLPatternInit) URLPatternInput;

[Exposed=(Window,Worker)]
interface URLPattern {
  constructor(URLPatternInput input, USVString baseURL, optional URLPatternOptions options = {});
  constructor(optional URLPatternInput input = {}, optional URLPatternOptions options = {});

  boolean test(optional URLPatternInput input = {}, optional USVString baseURL);

  URLPatternResult? exec(optional URLPatternInput input = {}, optional USVString baseURL);

  readonly attribute USVString protocol;
  readonly attribute USVString username;
  readonly attribute USVString password;
  readonly attribute USVString hostname;
  readonly attribute USVString port;
  readonly attribute USVString pathname;
  readonly attribute USVString search;
  readonly attribute USVString hash;

  readonly attribute boolean hasRegExpGroups;
};

dictionary URLPatternInit {
  USVString protocol;
  USVString username;
  USVString password;
  USVString hostname;
  USVString port;
  USVString pathname;
  USVString search;
  USVString hash;
  USVString baseURL;
};

dictionary URLPatternOptions {
  boolean ignoreCase = false;
};

dictionary URLPatternResult {
  sequence<URLPatternInput> inputs;

  URLPatternComponentResult protocol;
  URLPatternComponentResult username;
  URLPatternComponentResult password;
  URLPatternComponentResult hostname;
  URLPatternComponentResult port;
  URLPatternComponentResult pathname;
  URLPatternComponentResult search;
  URLPatternComponentResult hash;
};

dictionary URLPatternComponentResult {
  USVString input;
  record<USVString, (USVString or undefined)> groups;
};

URLPattern関連付けられたURLパターンURLパターン)を持ちます。

urlPattern = new URLPattern(input)
新しいURLPatternオブジェクトを構築します。 inputは各URLコンポーネント(例:hostname, pathnameなど)ごとに個別のパターンを含むオブジェクトです。省略されたコンポーネントはワイルドカードパターンがデフォルトとなります。さらに、inputには欠落しているコンポーネントの静的テキストパターンを提供するbaseURLプロパティを含めることができます。
urlPattern = new URLPattern(patternString, baseURL)
新しいURLPatternオブジェクトを構築します。 patternStringは1つ以上のコンポーネントに対するパターン構文を含むURL文字列です。 baseURLが指定されている場合、patternStringは相対指定が可能です。このコンストラクタは少なくとも空文字列値を常にセットし、コンポーネントをワイルドカードパターンにデフォルトしません。
urlPattern = new URLPattern(input, options)
新しいURLPatternオブジェクトを構築します。optionsはコンポーネントのマッチ方法に影響する追加設定オプションを含むオブジェクトです。現在はignoreCaseプロパティのみを持ち、trueにすると大文字小文字を区別しないマッチングが有効になります。

デフォルト、つまりoptions引数がない場合、マッチングは常に大文字小文字を区別します。

urlPattern = new URLPattern(patternString, baseURL, options)
新しいURLPatternオブジェクトを構築します。このオーバーロードは、patternStringオブジェクトからパターンを構築する際に、個々のコンポーネントや基準URLのパターンを記述するURLPatternOptionsオブジェクトをサポートします。
matches = urlPattern.test(input)
urlPatternが指定した引数にマッチするかテストします。inputは各URLコンポーネント(例:hostname, pathnameなど)を表す文字列を含むオブジェクトです。省略されたコンポーネントは空文字列として扱われます。さらに、inputには欠落したコンポーネントの値を提供するbaseURLプロパティを含めることができます。urlPatternがコンポーネント単位でinputにマッチすればtrueを返し、そうでなければfalseを返します。
matches = urlPattern.test(url, baseURL)
urlPatternが指定した引数にマッチするかテストします。urlはURL文字列です。baseURLが指定された場合、urlは相対指定が可能です。

urlPatternがコンポーネント単位でinputにマッチすればtrueを返し、そうでなければfalseを返します。

result = urlPattern.exec(input)
urlPatternを指定した引数に対して実行します。inputは各URLコンポーネント(例:hostname, pathnameなど)を表す文字列を含むオブジェクトです。省略されたコンポーネントは空文字列として扱われます。さらに、inputには欠落したコンポーネントの値を提供するbaseURLプロパティを含めることができます。

urlPatternがコンポーネント単位でinputにマッチした場合、結果を含むオブジェクトが返されます。マッチしたグループ値はresultオブジェクト内の各コンポーネントのグループオブジェクト(例:matches.pathname.groups.id)に格納されます。マッチしなかった場合、resultはnullとなります。

result = urlPattern.exec(url, baseURL)
urlPatternを指定した引数に対して実行します。urlはURL文字列です。baseURLが指定された場合、inputは相対指定が可能です。

urlPatternがコンポーネント単位でinputにマッチした場合、結果を含むオブジェクトが返されます。マッチしたグループ値はresultオブジェクト内の各コンポーネントのグループオブジェクト(例:matches.pathname.groups.id)に格納されます。マッチしなかった場合、resultはnullとなります。

urlPattern.protocol

urlPatternの正規化されたプロトコルパターン文字列を返します。

urlPattern.username

urlPatternの正規化されたユーザー名パターン文字列を返します。

urlPattern.password

urlPatternの正規化されたパスワードパターン文字列を返します。

urlPattern.hostname

urlPatternの正規化されたホスト名パターン文字列を返します。

urlPattern.port

urlPatternの正規化されたポートパターン文字列を返します。

urlPattern.pathname

urlPatternの正規化されたパス名パターン文字列を返します。

urlPattern.search

urlPatternの正規化された検索パターン文字列を返します。

urlPattern.hash

urlPatternの正規化されたハッシュパターン文字列を返します。

urlPattern.hasRegExpGroups

urlPatternが1つ以上の正規表現グループを含むかどうかを返します。

new URLPattern(input, baseURL, options) コンストラクタの手順は以下の通りです:
  1. initializethisinputbaseURLoptionsで実行します。

new URLPattern(input, options) コンストラクタの手順は以下の通りです:
  1. initializethisinput、null、optionsで実行します。

initialize URLPatternに対して、URLPatternthisURLPatternInputinput、文字列またはnullbaseURLURLPatternOptionsoptionsの手順は以下の通りです:
  1. this関連付けられたURLパターンに、createの結果(inputbaseURLoptions)をセットします。

protocol getterの手順は以下の通りです:
  1. this関連付けられたURLパターンprotocolコンポーネントパターン文字列を返します。

username getterの手順は以下の通りです:
  1. this関連付けられたURLパターンusernameコンポーネントパターン文字列を返します。

password getterの手順は以下の通りです:
  1. this関連付けられたURLパターンpasswordコンポーネントパターン文字列を返します。

hostname getterの手順は以下の通りです:
  1. this関連付けられたURLパターンhostnameコンポーネントパターン文字列を返します。

port getterの手順は以下の通りです:
  1. this関連付けられたURLパターンportコンポーネントパターン文字列を返します。

pathname getterの手順は以下の通りです:
  1. this関連付けられたURLパターンpathnameコンポーネントパターン文字列を返します。

search getterの手順は以下の通りです:
  1. this関連付けられたURLパターンsearchコンポーネントパターン文字列を返します。

hash getterの手順は以下の通りです:
  1. this関連付けられたURLパターンhashコンポーネントパターン文字列を返します。

hasRegExpGroups getterの手順は以下の通りです:
  1. もしthis関連URLパターン正規表現グループを持つ場合、trueを返す。

  2. falseを返します。

test(input, baseURL) メソッドの手順は以下の通り:
  1. resultを、マッチthis関連URLパターンinputbaseURL(与えられた場合)で実行した結果とする。

  2. もしresultがnullなら、falseを返す。

  3. trueを返す。

exec(input, baseURL) メソッドの手順は以下の通りです:
  1. matchの結果(this関連付けられたURLパターンinput、(あれば)baseURL)を返す。

1.3. URLパターン構造体

URLパターンは、以下の構造体項目を持つ構造体です:

コンポーネントは、以下の構造体項目を持つ構造体です:

1.4. 高レベルの操作

createURLPatternInput input、文字列またはnullbaseURL、およびURLPatternOptions optionsで行う場合:
  1. initをnullにする。

  2. inputスカラー値文字列の場合:

    1. initinputを使ってコンストラクタ文字列をパースするの結果を設定する。

    2. baseURLがnullであり、かつinit["protocol"] が存在しない場合、TypeErrorを投げる。

    3. baseURLがnullでない場合、セット init["baseURL"] にbaseURLを設定する。

  3. それ以外の場合:

    1. アサート: inputURLPatternInitである。

    2. baseURLがnullでない場合、TypeErrorを投げる。

    3. initinputを設定する。

  4. processedInitURLPatternInitを処理するの結果(init, "pattern", null, null, null, null, null, null, null, null)を設定する。

  5. « "protocol", "username", "password", "hostname", "port", "pathname", "search", "hash" »の各componentNameについて:

    1. processedInit[componentName]が存在しない場合、セットprocessedInit[componentName]に"*"を設定する。

  6. processedInit["protocol"] が特別なスキームであり、processedInit["port"] がデフォルトポートASCII数字で表す文字列の場合、processedInit["port"]を空文字列に設定する。

  7. urlPatternに新しいURLパターンを作成する。

  8. urlPatternprotocolコンポーネントprocessedInit["protocol"]、プロトコルを正規化するデフォルトオプションを使ってコンポーネントをコンパイルする結果を設定する。

  9. urlPatternusernameコンポーネントprocessedInit["username"]、ユーザー名を正規化するデフォルトオプションコンポーネントをコンパイルする結果を設定する。

  10. urlPatternpasswordコンポーネントprocessedInit["password"]、パスワードを正規化するデフォルトオプションコンポーネントをコンパイルする結果を設定する。

  11. processedInit["hostname"]についてhostnameパターンがIPv6アドレスかの結果がtrueであれば、urlPatternhostnameコンポーネントprocessedInit["hostname"]、IPv6ホスト名を正規化するホスト名オプションコンポーネントをコンパイルする結果を設定する。

  12. そうでなければ、urlPatternhostnameコンポーネントprocessedInit["hostname"]、ホスト名を正規化するホスト名オプションコンポーネントをコンパイルする結果を設定する。

  13. urlPatternportコンポーネントprocessedInit["port"]、ポートを正規化するデフォルトオプションコンポーネントをコンパイルする結果を設定する。

  14. compileOptionsデフォルトオプションのコピーを作成し、ignore caseプロパティにoptions["ignoreCase"]を設定する。

  15. urlPatternprotocolコンポーネントについてprotocolコンポーネントが特別なスキームにマッチするかの結果がtrueなら:

    1. pathCompileOptionspathnameオプションのコピーを作成し、ignore caseプロパティにoptions["ignoreCase"]を設定する。

    2. urlPatternpathnameコンポーネントprocessedInit["pathname"]、パス名を正規化するpathCompileOptionsコンポーネントをコンパイルする結果を設定する。

  16. そうでなければ、urlPatternpathnameコンポーネントprocessedInit["pathname"]、不透明なパス名を正規化するcompileOptionsコンポーネントをコンパイルする結果を設定する。

  17. urlPatternsearchコンポーネントprocessedInit["search"]、検索を正規化するcompileOptionsコンポーネントをコンパイルする結果を設定する。

  18. urlPatternhashコンポーネントprocessedInit["hash"]、ハッシュを正規化するcompileOptionsコンポーネントをコンパイルする結果を設定する。

  19. urlPatternを返す。

マッチするには、URLパターン urlPatternURLPatternInput または URL input、省略可能な文字列 baseURLString を指定して次の手順を実行します:
  1. protocol を空文字列にする。

  2. username を空文字列にする。

  3. password を空文字列にする。

  4. hostname を空文字列にする。

  5. port を空文字列にする。

  6. pathname を空文字列にする。

  7. search を空文字列にする。

  8. hash を空文字列にする。

  9. inputs を空のリストにする。

  10. inputURLであれば、appendinputシリアライズinputsへ追加する。

  11. それ以外の場合は、appendinputinputsへ追加する。

  12. inputURLPatternInit であれば:

    1. baseURLStringが指定されている場合はTypeErrorを投げる。

    2. applyResultinput、"url"、protocolusernamepasswordhostnameportpathnamesearchhashURLPatternInitを処理するの結果を設定する。例外が発生した場合はキャッチし、nullを返す。

    3. protocolapplyResult["protocol"]を設定する。

    4. usernameapplyResult["username"]を設定する。

    5. passwordapplyResult["password"]を設定する。

    6. hostnameapplyResult["hostname"]を設定する。

    7. portapplyResult["port"]を設定する。

    8. pathnameapplyResult["pathname"]を設定する。

    9. searchapplyResult["search"]を設定する。

    10. hashapplyResult["hash"]を設定する。

  13. それ以外の場合:

    1. urlinputを設定する。

    2. inputUSVStringの場合:

      1. baseURLをnullにする。

      2. baseURLStringが指定されていれば:

        1. baseURL基本URLパーサbaseURLStringで実行した結果を設定する。

        2. baseURLが失敗ならnullを返す。

        3. appendbaseURLStringinputsへ追加する。

      3. url基本URLパーサinputbaseURLで実行した結果を設定する。

      4. urlが失敗ならnullを返す。

    3. アサート: urlURLである。

    4. protocolurlschemeを設定する。

    5. usernameurlusernameを設定する。

    6. passwordurlpasswordを設定する。

    7. hostnameurlhostシリアライズまたは値がnullなら空文字列を設定する。

    8. porturlportシリアライズまたは値がnullなら空文字列を設定する。

    9. pathnameURLパスシリアライズの結果を設定する。

    10. searchurlqueryまたは値がnullなら空文字列を設定する。

    11. hashurlfragmentまたは値がnullなら空文字列を設定する。

  14. protocolExecResultRegExpBuiltinExec(urlPatternprotocolコンポーネント正規表現, protocol)を設定する。

  15. usernameExecResultRegExpBuiltinExec(urlPatternusernameコンポーネント正規表現, username)を設定する。

  16. passwordExecResultRegExpBuiltinExec(urlPatternpasswordコンポーネント正規表現, password)を設定する。

  17. hostnameExecResultRegExpBuiltinExec(urlPatternhostnameコンポーネント正規表現, hostname)を設定する。

  18. portExecResultRegExpBuiltinExec(urlPatternportコンポーネント正規表現, port)を設定する。

  19. pathnameExecResultRegExpBuiltinExec(urlPatternpathnameコンポーネント正規表現, pathname)を設定する。

  20. searchExecResultRegExpBuiltinExec(urlPatternsearchコンポーネント正規表現, search)を設定する。

  21. hashExecResultRegExpBuiltinExec(urlPatternhashコンポーネント正規表現, hash)を設定する。

  22. いずれかのExecResultがnullならnullを返す。

  23. resultに新しいURLPatternResultを設定する。

  24. result["inputs"]にinputsを設定する。

  25. result["protocol"]にコンポーネントマッチ結果を作成するurlPatternprotocolコンポーネント, protocol, protocolExecResult)の結果を設定する。

  26. result["username"]にコンポーネントマッチ結果を作成するurlPatternusernameコンポーネント, username, usernameExecResult)の結果を設定する。

  27. result["password"]にコンポーネントマッチ結果を作成するurlPatternpasswordコンポーネント, password, passwordExecResult)の結果を設定する。

  28. result["hostname"]にコンポーネントマッチ結果を作成するurlPatternhostnameコンポーネント, hostname, hostnameExecResult)の結果を設定する。

  29. result["port"]にコンポーネントマッチ結果を作成するurlPatternportコンポーネント, port, portExecResult)の結果を設定する。

  30. result["pathname"]にコンポーネントマッチ結果を作成するurlPatternpathnameコンポーネント, pathname, pathnameExecResult)の結果を設定する。

  31. result["search"]にコンポーネントマッチ結果を作成するurlPatternsearchコンポーネント, search, searchExecResult)の結果を設定する。

  32. result["hash"]にコンポーネントマッチ結果を作成するurlPatternhashコンポーネント, hash, hashExecResult)の結果を設定する。

  33. resultを返す。

URLパターン urlPattern正規表現グループを持つかは以下の手順でtrueを返す場合:
  1. urlPatternprotocolコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  2. urlPatternusernameコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  3. urlPatternpasswordコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  4. urlPatternhostnameコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  5. urlPatternportコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  6. urlPatternpathnameコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  7. urlPatternsearchコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  8. urlPatternhashコンポーネント正規表現グループを持つかがtrueならtrueを返す。

  9. falseを返す。

1.5. 内部仕様

コンポーネントをコンパイルするには、文字列inputエンコーディングコールバックencoding callbackoptionsoptionsを指定して次の手順を実行します:
  1. part listinputoptionsencoding callbackパターン文字列をパースするの結果を設定する。

  2. (regular expression string, name list)にpart listoptions正規表現と名前リストを生成するの結果を設定する。

  3. flagsを空文字列にする。

  4. optionsignore caseがtrueなら、flagsに"vi"を設定する。

  5. そうでなければflagsに"v"を設定する。

  6. regular expressionRegExpCreate(regular expression string, flags)の結果を設定する。例外が発生した場合はキャッチし、TypeErrorを投げる。

    仕様はすべてのマッチングに正規表現を使用しますが、これは必須ではありません。実装はpart listに対して直接マッチングしても構いません(例えばカスタム正規表現グループがない場合)。ただしカスタム正規表現がある場合は、コンポーネントをコンパイルするで即座に評価され、無効な場合はエラーを投げることが重要です。

  7. pattern stringpart listoptionsパターン文字列を生成するの結果を設定する。

  8. has regexp groupsをfalseにする。

  9. partpart listについて:

    1. parttypeが"regexp"なら、has regexp groupsをtrueにする。

  10. コンポーネントを新規作成し、パターン文字列pattern string正規表現regular expressionグループ名リストname list正規表現グループを持つかhas regexp groupsを設定して返す。

コンポーネントマッチ結果を作成するには、コンポーネントcomponent、文字列inputRegExpBuiltinExecの結果配列execResultを指定して次の手順を実行します:
  1. resultに新しいURLPatternComponentResultを設定する。

  2. result["input"]にinputを設定する。

  3. groupsrecord<USVString, (USVString またはundefined)>で初期化する。

  4. indexを1にする。

  5. indexGet(execResult, "length")未満の間:

    1. namecomponentグループ名リスト[index−1]を設定する。

    2. valueGet(execResult, ToString(index))を設定する。

    3. groups[name]にvalueを設定する。

    4. indexを1増やす。

  6. result["groups"]にgroupsを設定する。

  7. resultを返す。

ダミーURLを作成するには次の手順を実行します:
  1. dummyInputに"https://dummy.invalid/"を設定する。

  2. dummyInput基本URLパーサを実行した結果を返す。

デフォルトオプションは、options構造体であり、区切りコードポイントを空文字列、プレフィックスコードポイントを空文字列として設定します。

ホスト名オプションは、options構造体であり、区切りコードポイントを"."、プレフィックスコードポイントを空文字列として設定します。

パス名オプションは、options構造体であり、区切りコードポイントを"/"、プレフィックスコードポイントを"/"として設定します。

protocolコンポーネントが特別なスキームにマッチするかは、コンポーネントprotocol componentについて次の手順を実行します:
  1. special scheme listリストとしてすべての特別なスキームを格納する。

  2. schemespecial scheme listについて:

    1. test resultRegExpBuiltinExec(protocol component正規表現, scheme)を設定する。

    2. test resultがnullでなければtrueを返す。

  3. falseを返す。

hostnameパターンがIPv6アドレスかは、パターン文字列 inputについて次の手順を実行します:
  1. inputコードポイント長が2未満ならfalseを返す。

  2. input code pointsinputリストとしてコードポイントとして解釈したものを設定する。

  3. input code points[0]がU+005B([)ならtrueを返す。

  4. input code points[0]がU+007B({)かつinput code points[1]がU+005B([)ならtrueを返す。

  5. input code points[0]がU+005C(\)かつinput code points[1]がU+005B([)ならtrueを返す。

  6. falseを返す。

1.6. コンストラクタ文字列のパース

コンストラクタ文字列パーサは、構造体です。

コンストラクタ文字列パーサは、関連付けられたinput(文字列)を持ち、作成時に設定されなければなりません。

コンストラクタ文字列パーサは、関連付けられたtoken listトークンリスト)を持ち、作成時に設定されなければなりません。

コンストラクタ文字列パーサは、関連付けられたresultURLPatternInit)を持ち、初期値は新しいURLPatternInitです。

コンストラクタ文字列パーサは、関連付けられたcomponent start(数値)を持ち、初期値は0です。

コンストラクタ文字列パーサは、関連付けられたtoken index(数値)を持ち、初期値は0です。

コンストラクタ文字列パーサは、関連付けられたtoken increment(数値)を持ち、初期値は1です。

コンストラクタ文字列パーサは、関連付けられたgroup depth(数値)を持ち、初期値は0です。

コンストラクタ文字列パーサは、関連付けられたhostname IPv6 bracket depth(数値)を持ち、 初期値は0です。

コンストラクタ文字列パーサは、関連付けられたprotocol matches a special scheme flag(真偽値)を持ち、初期値はfalseです。

コンストラクタ文字列パーサは、関連付けられたstate(文字列)を持ち、初期値は"init"です。次のいずれかでなければなりません:

URLPatternのコンストラクタ文字列アルゴリズムは、基本URLパーサのアルゴリズムと非常に似ていますが、いくつかの違いにより直接利用はできません。

まず、URLPatternのコンストラクタ文字列パーサは"lenient"tokenize policyで生成されたトークンを操作します。対して基本URLパーサはコードポイントを操作します。トークンで操作することで、URLPatternのコンストラクタ文字列パーサは、重要なパターン構文となるコードポイントと、URLコンポーネントの区切りになりうるコードポイントを容易に区別できます。例えば、"https://a.c:hmm.example.com:8080"の":hmm"のような名前付きグループをポート番号と混同せず簡単に扱うことができます。

次に、URLPatternのコンストラクタ文字列パーサは、基本URLパーサのようにすべてのコードポイントにURL正規化を適用しない必要があります。代わりに、各コンポーネントのパターン文字列を後でコンパイルする際に、安全だと分かっている部分だけ正規化します。

最後に、URLPatternのコンストラクタ文字列パーサは基本URLパーサのステートマシンの一部を扱いません。例えば、バックスラッシュはすべてパターン文字とみなされ、過剰なエスケープが必要となるため特別扱いしません。また、このパーサはファイルURLのホスト名など、URLパースアルゴリズムのより特殊な部分は扱わない場合があります。このパーサの目的は、最も一般的なURLを扱いつつ、ニッチなケースは代わりにURLPatternInitコンストラクタで対応できるようにすることです。

コンストラクタ文字列アルゴリズムでは、pathname、search、hashは前のコンポーネントが指定されていて後のコンポーネントが省略されている場合にワイルドカードとなります。例えば "https://example.com/foo" は任意のsearchと任意のhashにマッチします。同様に、"https://example.com" はそのオリジン上の任意のURLにマッチします。これはURLPatternInitを処理するの注記にある、より具体的なコンポーネントの概念に類似しています(例えばsearchはpathnameより具体的)が、コンストラクタ構文ではより具体的なコンポーネントのみを指定して、より抽象的なコンポーネントを省略できるケースは少数です。

usernameとpasswordコンポーネントは、明示的に指定しない限り常にワイルドカードとなります。

hostnameが指定され、portが指定されていない場合、portはデフォルトポートとみなされます。任意のポートにマッチさせたい場合は :* を明示的に記述する必要があります。例えば "https://*" はポート443上の任意のHTTPSオリジン、"https://*:*" は任意のポート上の任意のHTTPSオリジンです。

コンストラクタ文字列をパースするには、文字列inputを指定して次の手順を実行します:
  1. parserに新しいコンストラクタ文字列パーサを作成し、inputinputtoken listinputと"lenient"でtokenizeした結果を設定する。

  2. While parsertoken indexparsertoken listサイズ未満の場合:

    1. parsertoken incrementを1に設定する。

      parseループの各イテレーションで、parsertoken indextoken increment分だけ増加します。通常は1ですが、場合によっては0に設定されることがあります。token incrementはループの先頭で常に1にリセットされます。

    2. parsertoken list[parsertoken index]のtypeが"end"の場合:

      1. parserstateが"init"の場合:

        "init"stateで文字列末尾に到達した場合、プロトコールの終端が見つからず、相対URLPatternのコンストラクタ文字列である必要があります。

        1. rewindparserで実行する。

          次に、相対パターンがどのコンポーネントから始まるか判定します。相対pathnameが最も一般的ですが、URLやURLPatternのコンストラクタ文字列はsearchやhashコンポーネントから始まることもあります。

        2. is a hash prefixparserで実行した結果がtrueなら、change stateparser、"hash"および1で実行する。

        3. それ以外でis a search prefixparserで実行した結果がtrueなら:

          1. change stateparser、"search"および1で実行する。

        4. それ以外:

          1. change stateparser、"pathname"および0で実行する。

        5. parsertoken indextoken increment分だけ増やす。

        6. Continue

      2. parserstateが"authority"の場合:

        "authority"stateで文字列末尾に到達した場合、"@"が見つからず、usernameやpasswordはありません。

        1. rewind and set stateparser、"hostname"で実行する。

        2. parsertoken indextoken increment分だけ増やす。

        3. Continue

      3. change stateparser、"done"および0で実行する。

      4. Break

    3. is a group openparserで実行した結果がtrueの場合:

      "{ ... }"パターングループ内のコードポイントはすべて無視されます。パターングループ内にURLコンポーネント境界を許すのは不適切です(例: "https://example.c{om/fo}o")。well formedパターン文字列ではサポートされていませんが、ネストされたグループにも対応しパーサの混乱を避けます。

      このロジックはregexpや名前付きグループには不要です。これらはtoken化アルゴリズムで単一トークンにまとめられるためです。

      1. parsergroup depthを1増やす。

      2. parsertoken indextoken increment分だけ増やす。

      3. Continue

    4. parsergroup depthが0より大きい場合:

      1. is a group closeparserで実行した結果がtrueなら、parsergroup depthを1減らす。

      2. それ以外:

        1. parsertoken indextoken increment分だけ増やす。

        2. Continue

    5. parserstateごとに以下の手順を実行:

      "init"
      1. is a protocol suffixparserで実行しtrueなら:

        1. rewind and set stateparserと"protocol"で実行する。

      "protocol"
      1. is a protocol suffixparserで実行しtrueなら:

        1. compute protocol matches a special scheme flagparserで実行する。

          プロトコールコンポーネントを即座にコンパイルし、特別なスキームにマッチするか判定します。マッチする場合は特別なルールが適用されます。たとえばpathnameが"/"になるか、username/password/hostname/portコンポーネントを探すかどうか決まります。authority slashesもこれらのコンポーネント探索に影響します。そうでなければ「不透明パスURL」としてpathnameへ進みます。

        2. next stateに"pathname"を設定する。

        3. skipに1を設定する。

        4. next is authority slashesparserで実行しtrueなら:

          1. next stateに"authority"を設定する。

          2. skipに3を設定する。

        5. それ以外でparserprotocol matches a special scheme flagがtrueなら、next stateに"authority"を設定する。

        6. change stateparsernext stateskipで実行する。

      "authority"
      1. is an identity terminatorparserで実行しtrueなら、rewind and set stateparser、"username"で実行する。

      2. それ以外で以下のいずれかがtrueなら:

        の場合、rewind and set stateparser、"hostname"で実行する。

      "username"
      1. is a password prefixparserで実行しtrueなら、change stateparser、"password"および1で実行する。

      2. それ以外でis an identity terminatorparserで実行しtrueなら、change stateparser、"hostname"および1で実行する。

      "password"
      1. is an identity terminatorparserで実行しtrueなら、change stateparser、"hostname"および1で実行する。

      "hostname"
      1. is an IPv6 openparserで実行しtrueなら、parserhostname IPv6 bracket depthを1増やす。

      2. それ以外でis an IPv6 closeparserで実行しtrueなら、parserhostname IPv6 bracket depthを1減らす。

      3. それ以外でis a port prefixparserで実行し、かつparserhostname IPv6 bracket depthが0なら、change stateparser、"port"および1で実行する。

      4. それ以外でis a pathname startparserで実行しtrueなら、change stateparser、"pathname"および0で実行する。

      5. それ以外でis a search prefixparserで実行しtrueなら、change stateparser、"search"および1で実行する。

      6. それ以外でis a hash prefixparserで実行しtrueなら、change stateparser、"hash"および1で実行する。

      "port"
      1. is a pathname startparserで実行しtrueなら、change stateparser、"pathname"および0で実行する。

      2. それ以外でis a search prefixparserで実行しtrueなら、change stateparser、"search"および1で実行する。

      3. それ以外でis a hash prefixparserで実行しtrueなら、change stateparser、"hash"および1で実行する。

      "pathname"
      1. is a search prefixparserで実行しtrueなら、change stateparser、"search"および1で実行する。

      2. それ以外でis a hash prefixparserで実行しtrueなら、change stateparser、"hash"および1で実行する。

      "search"
      1. is a hash prefixparserで実行しtrueなら、change stateparser、"hash"および1で実行する。

      "hash"
      1. 何もしない。

      "done"
      1. Assert: このステップには到達しません。

    6. parsertoken indextoken increment分だけ増やす。

  3. parserresultが"hostname"を含み、かつ"port"を含まない場合、parserresult["port"]に空文字列を設定する。

    これは特例です。著者がportを指定しない場合、通常はデフォルトポートを意図しています。任意のポートを許可する場合はワイルドカードを明示する必要があります。例えば"https://example.com/*"は"https://example.com:8443/"で始まるURL(異なるオリジン)にはマッチしません。
  4. parserresultを返す。

状態を変更するには、 コンストラクタ文字列パーサparserstatenew state、数値skipを指定して次の手順を実行します:
  1. parserstateが"init"、"authority"、"done"以外の場合、 parserresult[parserstate]にコンポーネント文字列を作成するの結果を設定する。

  2. parserstateが"init"でなく、new stateが"done"でない場合:

    1. parserstateが"protocol"、 "authority"、 "username"、 または"password"、 かつnew stateが"port"、"pathname"、 "search"、 または"hash"であり、 parserresult["hostname"] が存在しない場合、parserresult["hostname"] に空文字列を設定する。

    2. parserstateが"protocol"、 "authority"、 "username"、 "password"、 "hostname"、 または"port"、 かつnew stateが"search"または"hash"であり、 parserresult["pathname"] が存在しない場合:

      1. parserprotocol matches a special scheme flagがtrueなら、 parserresult["pathname"] に"/"を設定する。

      2. それ以外の場合はparserresult["pathname"] に空文字列を設定する。

    3. parserstateが"protocol"、 "authority"、 "username"、 "password"、 "hostname"、 "port"、 または"pathname"、 かつnew stateが"hash"であり、 parserresult["search"] が存在しない場合、 parserresult["search"] に空文字列を設定する。

  3. parserstatenew stateを設定する。

  4. parsertoken indexskip分だけ増やす。

  5. parsercomponent startparsertoken indexを設定する。

  6. parsertoken incrementを0に設定する。

巻き戻すには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. parsertoken indexparsercomponent startを設定する。

  2. parsertoken incrementを0に設定する。

巻き戻して状態を設定するには、コンストラクタ文字列パーサparserstatestateを指定して次の手順を実行します:
  1. 巻き戻すparserで実行する。

  2. parserstatestateを設定する。

安全なトークンを取得するには、コンストラクタ文字列パーサparser、数値indexを指定して次の手順を実行します:
  1. indexparsertoken listサイズ未満なら、 parsertoken list[index]を返す。

  2. アサート: parsertoken listサイズは1以上。

  3. last indexparsertoken listサイズ−1を設定する。

  4. tokenparsertoken list[last index]を設定する。

  5. アサート: tokentypeは"end"である。

  6. tokenを返す。

特殊でないパターン文字か判定するには、コンストラクタ文字列パーサparser、数値index、文字列valueを指定して次の手順を実行します:
  1. token安全なトークンを取得するparserindexで実行した結果を設定する。

  2. tokenvaluevalueでなければfalseを返す。

  3. 以下のいずれかがtrueの場合:

    場合はtrueを返す。

  4. falseを返す。

プロトコールサフィックスか判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、":"で実行した結果を返す。

次がauthorityスラッシュか判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index+1、"/"で実行した結果がfalseならfalseを返す。

  2. 特殊でないパターン文字か判定するparserparsertoken index+2、"/"で実行した結果がfalseならfalseを返す。

  3. trueを返す。

identity終端子か判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、"@"で実行した結果を返す。

パスワードプレフィックスか判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、":"で実行した結果を返す。

ポートプレフィックスか判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、":"で実行した結果を返す。

pathname開始か判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、"/"で実行した結果を返す。

searchプレフィックスか判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、"?"で実行した結果がtrueならtrueを返す。

  2. parsertoken list[parsertoken index]のvalueが"?"でなければfalseを返す。

  3. previous indexparsertoken index−1を設定する。

  4. previous indexが0未満ならtrueを返す。

  5. previous token安全なトークンを取得するparserprevious indexで実行した結果を設定する。

  6. 以下のいずれかがtrueならfalseを返す:

  7. trueを返す。

hashプレフィックスか判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、"#"で実行した結果を返す。

グループ開始か判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. parsertoken list[parsertoken index]のtypeが"open"ならtrueを返す。

  2. それ以外はfalseを返す。

グループ終了か判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. parsertoken list[parsertoken index]のtypeが"close"ならtrueを返す。

  2. それ以外はfalseを返す。

IPv6開始か判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、"["で実行した結果を返す。

IPv6終了か判定するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. 特殊でないパターン文字か判定するparserparsertoken index、"]"で実行した結果を返す。

コンポーネント文字列を作成するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. アサート: parsertoken indexparsertoken listサイズ未満。

  2. tokenparsertoken list[parsertoken index]を設定する。

  3. component start token安全なトークンを取得するparserparsercomponent startで実行した結果を設定する。

  4. component start input indexcomponent start tokenindexを設定する。

  5. end indextokenindexを設定する。

  6. parserinputcomponent start input indexからend indexまでのコードポイント部分文字列を返す。

プロトコールが特別なスキームにマッチするかフラグを計算するには、コンストラクタ文字列パーサparserを指定して次の手順を実行します:
  1. protocol stringコンポーネント文字列を作成するparserで実行した結果を設定する。

  2. protocol componentコンポーネントをコンパイルするprotocol stringプロトコルを正規化するデフォルトオプションで実行した結果を設定する。

  3. protocolコンポーネントが特別なスキームにマッチするかprotocol componentで実行しtrueなら、parserprotocol matches a special scheme flagにtrueを設定する。

2. パターン文字列

パターン文字列は、対象となる文字列の集合にマッチするように記述された文字列です。well formedなパターン文字列は特定のパターン構文に従います。このパターン構文は、人気のあるJavaScriptライブラリ path-to-regexp の構文に直接基づいています。

パースすることで、パートリストが生成され、パターン文字列がマッチするためにコンポーネント文字列に何が順番に現れるべきかを説明します。

パターン文字列にはキャプチャグループを含めることができ、デフォルトでは最短一致でグループ化され、コンポーネント固有の区切り文字(pathnameなら/、hostnameなら.)までマッチします。例えば、pathnameのパターン "/blog/:title" は "/blog/hello-world" にはマッチしますが "/blog/2012/02" にはマッチしません。

括弧で囲んだ正規表現を使うこともでき、pathnameのパターン "/blog/:year(\d+)/:month(\d+)" は "/blog/2012/02" にマッチします。

グループはオプションや繰り返しにすることもできます。例えば、pathnameのパターン "/products/:id?" は "/products" と "/products/2" の両方にマッチします("/products/" にはマッチしません)。pathnameではグループは自動的に先頭に/が必要ですが、これを避けたい場合は明示的に区切ることができ、"/products/{:id}?" のように記述します。

フルワイルドカード*も使え、例えばpathnameパターン "/products/*" のようにできるだけ多くマッチさせることができます。

2.1. パターン文字列のパース

2.1.1. トークン

トークンリストは、リストであり、ゼロ個以上のトークン構造体を含みます。

トークンは、構造体であり、 パターン文字列内の一つの字句トークンを表します。

トークンには関連付けられたtype(文字列)があり、初期値は"invalid-char"です。次のいずれかでなければなりません:

"open"
このトークンはU+007B({)コードポイントを表します。
"close"
このトークンはU+007D(})コードポイントを表します。
"regexp"
このトークンは"(<正規表現>)"形式の文字列を表します。正規表現はASCIIコードポイントのみで構成されている必要があります。
"name"
このトークンは":<name>"形式の文字列を表します。name値はJavaScript識別子として許容されるコードポイントに制限されます。
"char"
このトークンは特別な構文的意味を持たない有効なパターンコードポイントを表します。
"escaped-char"
このトークンはバックスラッシュでエスケープされたコードポイント(例: "\<char>")を表します。
"other-modifier"
このトークンは、マッチンググループ修飾子(U+003F(?)、U+002B(+))を表します。
"asterisk"
このトークンはU+002A(*)コードポイントを表し、ワイルドカードマッチンググループまたはマッチンググループ修飾子となります。
"end"
このトークンパターン文字列の終端を表します。
"invalid-char"
このトークンはパターン内で無効なコードポイントを表します。これはコードポイント自体が原因の場合もあれば、パターン内で他の構文要素との相対的位置が原因の場合もあります。

トークンには関連付けられたindex(数値)があり、初期値は0です。これはパターン文字列内でこのトークンが表す最初のコードポイントの位置です。

トークンには関連付けられたvalue(文字列)があり、初期値は空文字列です。これはパターン文字列内でこのトークンが表すコードポイントを含みます。

2.1.2. トークン化

トークン化ポリシーは、"strict" または "lenient"のいずれかでなければならない文字列です。

トークナイザは、構造体です。

トークナイザには関連付けられたinputパターン文字列、初期値は空文字列)があります。

トークナイザには関連付けられたpolicyトークン化ポリシー、初期値は"strict")があります。

トークナイザには関連付けられたtoken listトークンリスト、初期値は空のリスト)があります。

トークナイザには関連付けられたindex(数値、初期値は0)があります。

トークナイザには関連付けられたnext index(数値、初期値は0)があります。

トークナイザには関連付けられたcode point(Unicodeコードポイント、初期値はnull)があります。

トークン化するには、文字列inputトークン化ポリシーpolicyを指定して次の手順を実行します:
  1. tokenizerに新しいトークナイザを作成する。

  2. tokenizerinputinputを設定する。

  3. tokenizerpolicypolicyを設定する。

  4. tokenizerindextokenizerinputコードポイント長未満の間:

    1. 次のコードポイントを取得するtokenizertokenizerindexで実行する。

    2. tokenizercode pointがU+002A(*)の場合:

      1. デフォルト位置と長さでトークンを追加するtokenizer、"asterisk"で実行する。

      2. Continue

    3. tokenizercode pointがU+002B(+)またはU+003F(?)の場合:

      1. デフォルト位置と長さでトークンを追加するtokenizer、"other-modifier"で実行する。

      2. Continue

    4. tokenizercode pointがU+005C(\)の場合:

      1. tokenizerindextokenizerinputコードポイント長−1と等しい場合:

        1. トークン化エラー処理tokenizertokenizernext indextokenizerindexで実行する。

        2. Continue

      2. escaped indextokenizernext indexを設定する。

      3. 次のコードポイントを取得するtokenizerで実行する。

      4. デフォルト長さでトークンを追加するtokenizer、"escaped-char"、tokenizernext indexescaped indexで実行する。

      5. Continue

    5. tokenizercode pointがU+007B({)の場合:

      1. デフォルト位置と長さでトークンを追加するtokenizer、"open"で実行する。

      2. Continue

    6. tokenizercode pointがU+007D(})の場合:

      1. デフォルト位置と長さでトークンを追加するtokenizer、"close"で実行する。

      2. Continue

    7. tokenizercode pointがU+003A(:)の場合:

      1. name positiontokenizernext indexを設定する。

      2. name startname positionを設定する。

      3. name positiontokenizerinputコードポイント長未満の間:

        1. 次のコードポイントを取得するtokenizername positionで実行する。

        2. first code pointname position==name startならtrue、そうでなければfalse。

        3. valid code point有効なnameコードポイントか判定tokenizercode pointfirst code pointで実行した結果を設定する。

        4. valid code pointがfalseならbreak

        5. name positiontokenizernext indexを設定する。

      4. name positionname start以下の場合:

        1. トークン化エラー処理tokenizername starttokenizerindexで実行する。

        2. Continue

      5. デフォルト長さでトークンを追加するtokenizer、"name"、name positionname startで実行する。

      6. Continue

    8. tokenizercode pointがU+0028(()の場合:

      1. depthに1を設定する。

      2. regexp positiontokenizernext indexを設定する。

      3. regexp startregexp positionを設定する。

      4. errorにfalseを設定する。

      5. regexp positiontokenizerinputコードポイント長未満の間:

        1. 次のコードポイントを取得するtokenizerregexp positionで実行する。

        2. tokenizercode pointASCIIコードポイントでなければ:

          1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

          2. errorにtrueを設定する。

          3. Break

        3. regexp position==regexp startかつtokenizercode pointがU+003F(?)の場合:

          1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

          2. errorにtrueを設定する。

          3. Break

        4. tokenizercode pointがU+005C(\)の場合:

          1. regexp position==tokenizerinputコードポイント長−1の場合:

            1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

            2. errorにtrueを設定する。

            3. Break

          2. 次のコードポイントを取得するtokenizerで実行する。

          3. tokenizercode pointASCIIコードポイントでなければ:

            1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

            2. errorにtrueを設定する。

            3. Break

          4. regexp positiontokenizernext indexを設定する。

          5. Continue

        5. tokenizercode pointがU+0029())の場合:

          1. depthを1減らす。

          2. depthが0の場合:

            1. regexp positiontokenizernext indexを設定する。

            2. Break

        6. それ以外でtokenizercode pointがU+0028(()の場合:

          1. depthを1増やす。

          2. regexp position==tokenizerinputコードポイント長−1の場合:

            1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

            2. errorにtrueを設定する。

            3. Break

          3. temporary positiontokenizernext indexを設定する。

          4. 次のコードポイントを取得するtokenizerで実行する。

          5. tokenizercode pointがU+003F(?)でない場合:

            1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

            2. errorにtrueを設定する。

            3. Break

          6. tokenizernext indextemporary positionを設定する。

        7. regexp positiontokenizernext indexを設定する。

      6. errorがtrueならcontinue

      7. depthが0でなければ:

        1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

        2. Continue

      8. regexp lengthregexp positionregexp start−1を設定する。

      9. regexp lengthが0の場合:

        1. トークン化エラー処理tokenizerregexp starttokenizerindexで実行する。

        2. Continue

      10. トークンを追加するtokenizer、"regexp"、regexp positionregexp startregexp lengthで実行する。

      11. Continue

    9. デフォルト位置と長さでトークンを追加するtokenizer、"char"で実行する。

  5. デフォルト長さでトークンを追加するtokenizer、"end"、tokenizerindextokenizerindexで実行する。

  6. tokenizertoken listを返す。

次のコードポイントを取得するには、トークナイザtokenizerを指定して次の手順を実行します:
  1. tokenizercode pointに、tokenizerinputtokenizernext indexで示される位置のUnicodeコードポイントを設定する。

  2. tokenizernext indexを1増やす。

指定位置で次のコードポイントを取得するには、トークナイザtokenizer、数値indexを指定して次の手順を実行します:
  1. tokenizernext indexindexを設定する。

  2. 次のコードポイントを取得するtokenizerで実行する。

トークンを追加するには、トークナイザtokenizertypetype、数値next position、数値value position、数値value lengthを指定して次の手順を実行します:
  1. tokenに新しいトークンを作成する。

  2. tokentypetypeを設定する。

  3. tokenindextokenizerindexを設定する。

  4. tokenvalueに、tokenizerinput内のvalue positionからvalue length分のコードポイント部分文字列を設定する。

  5. appendtokentokenizertoken listの末尾に追加する。

  6. tokenizerindexnext positionを設定する。

デフォルト長さでトークンを追加するには、トークナイザtokenizertypetype、数値next position、数値value positionを指定して次の手順を実行します:
  1. computed lengthnext positionvalue positionを設定する。

  2. トークンを追加するtokenizertypenext positionvalue positioncomputed lengthで実行する。

デフォルト位置と長さでトークンを追加するには、トークナイザ tokenizertypetypeを指定して次の手順を実行します:
  1. デフォルト長さでトークンを追加するtokenizertypetokenizernext indextokenizerindexで実行する。

トークン化エラー処理には、トークナイザtokenizer、数値next position、数値value positionを指定して次の手順を実行します:
  1. tokenizerpolicyが"strict"なら、TypeErrorを投げる。

  2. アサート: tokenizerpolicyは"lenient"である。

  3. デフォルト長さでトークンを追加するtokenizer、"invalid-char"、next positionvalue positionで実行する。

有効なnameコードポイントか判定には、Unicodecode point、真偽値firstを指定して次の手順を実行します:
  1. firstがtrueなら、code pointIdentifierStartコードポイント集合に含まれるかどうかをチェックした結果を返す。

  2. それ以外の場合、code pointIdentifierPartコードポイント集合に含まれるかどうかをチェックした結果を返す。

2.1.3. パーツ

パートリストは、リストであり、0個以上のパートを含みます。

パートは、パーサーの構造体であり、1つのパターン文字列の一部を表します。最大1つのマッチンググループ、固定テキストのプレフィックス、固定テキストのサフィックス、修飾子を含むことができます。最小では、1つの固定テキスト文字列または1つのマッチンググループのみを含むこともできます。

パートには、関連付けられたタイプ(文字列)があり、作成時に設定する必要があります。次のいずれかでなければなりません:

"fixed-text"
パートは単純な固定テキスト文字列を表します。
"regexp"
パートはカスタム正規表現によるマッチンググループを表します。
"segment-wildcard"
パートは、次のセパレーターコードポイントまでのコードポイントにマッチするマッチンググループを表します。これは通常、カスタム正規表現を持たない「:foo」のような名前付きグループで使用されます。
"full-wildcard"
パートは、すべてのコードポイントにグリーディにマッチするマッチンググループを表します。これは通常、「*」ワイルドカードマッチンググループで使用されます。

パートには、関連付けられた(文字列)があり、作成時に設定する必要があります。

パートには、関連付けられた修飾子(文字列)があり、作成時に設定する必要があります。次のいずれかでなければなりません:

"none"
パートには修飾子がありません。
"optional"
パートには、U+003F(?)コードポイントによって示されるオプションの修飾子があります。
"zero-or-more"
パートには、U+002A(*)コードポイントによって示される「0回以上」の修飾子があります。
"one-or-more"
パートには、U+002B(+)コードポイントによって示される「1回以上」の修飾子があります。

パートには、関連付けられた名前(文字列)があり、初期値は空文字列です。

パートには、関連付けられたプレフィックス(文字列)があり、初期値は空文字列です。

パートには、関連付けられたサフィックス(文字列)があり、初期値は空文字列です。

2.1.4. オプション

オプション 構造体は、パターン文字列の動作を制御するさまざまな設定を含みます。これらのオプションは元々path-to-regexpから来ています。現行標準では、URLPattern仕様内で変更されるオプションのみを含み、他のオプションは除外します。比較のために、この仕様はpath-to-regexpと同様にstrictstartendが常にfalseとなります。

オプションには、関連付けられたデリミターコードポイント(文字列)があり、作成時に設定する必要があります。1つのASCIIコードポイントまたは空文字列でなければなりません。このコードポイントはセグメントセパレーターとして扱われ、デフォルトで「:foo」の名前付きグループがどこまでマッチするかを決定するために使用されます。例えば、デリミターコードポイントが「/」の場合、「/:foo」は「/bar」にマッチしますが、「/bar/baz」にはマッチしません。デリミターコードポイントが空文字列の場合、上記のパターンは両方の文字列にマッチします。

オプションには、関連付けられたプレフィックスコードポイント(文字列)があり、作成時に設定する必要があります。1つのASCIIコードポイントまたは空文字列でなければなりません。このコードポイントは、マッチグループの直前に現れた場合、自動プレフィックスとして扱われます。これは、マッチグループがオプションまたは繰り返しに変更された場合に重要です。例えば、プレフィックスコードポイントが「/」の場合、「/foo/:bar?/baz」では「:bar」の前の「/」が、名前付きグループとともにオプションのプレフィックスとして扱われます。したがって、この例のパターンは「/foo/baz」にもマッチします。

オプションには、関連付けられた大文字・小文字を無視する(ブール値)があり、作成時に設定する必要があります。デフォルトはfalseです。設定値(trueまたはfalse)に応じて、このフラグは大文字・小文字を区別するかどうかを制御します。比較のために、このフラグはpath-to-regexpsensitiveオプションの否定として考えることができます。

2.1.5. パース

エンコーディングコールバックは、与えられた文字列inputを受け取る抽象アルゴリズムです。inputは、パターン文字列の単純なテキスト部分となります。実装するアルゴリズムはinputを検証し、エンコードします。エンコードされた文字列を返すか、例外を投げなければなりません。

パターンパーサーは、構造体です。

パターンパーサーには、関連付けられたトークンリストトークンリスト)があり、初期値は空のリストです。

パターンパーサーには、関連付けられたエンコーディングコールバックエンコーディングコールバック)があり、作成時に設定する必要があります。

パターンパーサーには、関連付けられたセグメントワイルドカード正規表現(文字列)があり、作成時に設定する必要があります。

パターンパーサーには、関連付けられたパートリストパートリスト)があり、初期値は空のリストです。

パターンパーサーには、関連付けられた保留中の固定値(文字列)があり、初期値は空文字列です。

パターンパーサーには、関連付けられたインデックス(数値)があり、初期値は0です。

パターンパーサーには、関連付けられた次の数値名(数値)があり、初期値は0です。

パターン文字列をパースするためには、パターン文字列inputオプションoptionsエンコーディングコールバックencoding callbackを与える:
  1. parserを新しいパターンパーサーとして生成し、そのエンコーディングコールバックencoding callbackに設定し、セグメントワイルドカード正規表現generate a segment wildcard regexpoptionsで実行した結果に設定する。

  2. parserトークンリストtokenizeinputと"strict"で実行した結果に設定する。

  3. parserインデックスparserトークンリストサイズより小さい間:

    この最初のセクションでは、以下のシーケンスを探します: <prefix char><name><regexp><modifier>。これらのトークンは0個からすべて含まれる場合があります。

    "/:foo(bar)?"
    すべてのトークンが含まれています。
    "/"
    一つの"char"トークン
    ":foo"
    一つの"name"トークン
    "(bar)"
    一つの"regexp"トークン
    "/:foo"
    "char"と"name"トークン
    "/(bar)"
    "char"と"regexp" トークン
    "/:foo?"
    "char"、"name"、および "other-modifier"トークン
    "/(bar)?"
    "char"、"regexp"、 および"other-modifier"トークン
    1. char tokentry to consume a tokenparserと"char"で実行した結果とする。

    2. name tokentry to consume a tokenparserと"name"で実行した結果とする。

    3. regexp or wildcard tokentry to consume a regexp or wildcard tokenparsername tokenで実行した結果とする。

    4. もしname tokenがnullでない、またはregexp or wildcard tokenがnullでない場合:

      マッチグループがある場合は、パートを直ちに追加する必要があります。

      1. prefixを空文字列とする。

      2. もしchar tokenがnullでなければ、prefixchar tokenに設定する。

      3. もしprefixが空文字列でなく、かつoptionsプレフィックスコードポイントでない場合:

        1. parser保留中の固定値の末尾にprefixを追加する。

        2. prefixを空文字列に設定する。

      4. maybe add a part from the pending fixed valueparserで実行する。

      5. modifier tokentry to consume a modifier tokenparserで実行した結果とする。

      6. add a partparserprefixname tokenregexp or wildcard token、空文字列、およびmodifier tokenで実行する。

      7. 続行

    5. fixed tokenchar tokenとする。

      マッチグループがない場合は、固定テキストをバッファリングする必要があります。できる限り多くのテキストを収集し、"fixed-text"パートとして追加します。

    6. もしfixed tokenがnullなら、fixed tokentry to consume a tokenparserと"escaped-char"で実行した結果に設定する。

    7. もしfixed tokenがnullでなければ:

      1. fixed tokenparser保留中の固定値に追加する。

      2. 続行

    8. open tokentry to consume a tokenparserと"open"で実行した結果とする。

      次に、 <open><char prefix><name><regexp><char suffix><close><modifier> のシーケンスを探します。openとcloseは必須ですが、他のトークンは必須ではありません。

      "{a:foo(bar)b}?"
      すべてのトークンが存在します。
      "{:foo}?"
      "open"、"name"、"close"、および"other-modifier"トークンが存在します。
      "{(bar)}?"
      "open"、"regexp"、"close"、および"other-modifier"トークンが存在します。
      "{ab}?"
      "open"、"char"、"close"、および"other-modifier"トークンが存在します。
    9. もしopen tokenがnullでなければ:

      1. prefixconsume textparserで実行した結果とする。

      2. name tokentry to consume a tokenparserと"name"で実行した結果とする。

      3. regexp or wildcard tokentry to consume a regexp or wildcard tokenparsername tokenで実行した結果とする。

      4. suffixconsume textparserで実行した結果とする。

      5. consume a required tokenparserと"close"で実行する。

      6. modifier tokentry to consume a modifier tokenparserで実行した結果とする。

      7. add a partparserprefixname tokenregexp or wildcard tokensuffix、およびmodifier tokenで実行する。

      8. 続行

    10. maybe add a part from the pending fixed valueparserで実行する。

    11. consume a required tokenparserと"end"で実行する。

  4. parserパートリストを返す。

フルワイルドカード正規表現値は文字列".*"です。

セグメントワイルドカード正規表現を生成するためには、オプションoptionsを与える:
  1. resultを"[^"とする。

  2. resultの末尾に、optionsデリミターコードポイントescape a regexp stringで実行した結果を追加する。

  3. resultの末尾に"]+?"を追加する。

  4. resultを返す。

トークンを消費しようとするためには、パターンパーサーparsertypetypeを与える:
  1. アサートparserインデックスparserトークンリストサイズより小さい。

  2. next tokenparserトークンリスト[parserインデックス]とする。

  3. もしnext tokentypetypeでないならnullを返す。

  4. parserインデックスを1増やす。

  5. next tokenを返す。

修飾子トークンを消費しようとするためには、パターンパーサーparserを与える:
  1. tokenトークンを消費しようとするparserと"other-modifier"で実行した結果とする。

  2. もしtokenがnullでなければ、tokenを返す。

  3. tokenトークンを消費しようとするparserと"asterisk"で実行した結果に設定する。

  4. tokenを返す。

正規表現またはワイルドカードトークンを消費しようとするためには、パターンパーサーparserトークンname tokenを与える:
  1. tokenトークンを消費しようとするparserと"regexp"で実行した結果とする。

  2. もしname tokenがnullかつtokenがnullなら、tokenトークンを消費しようとするparserと"asterisk"で実行した結果に設定する。

  3. tokenを返す。

必須トークンを消費するためには、パターンパーサーparsertypetypeを与える:
  1. resultトークンを消費しようとするparsertypeで実行した結果とする。

  2. もしresultがnullなら、TypeErrorを投げる。

  3. resultを返す。

テキストを消費するためには、パターンパーサーparserを与える:
  1. resultを空文字列とする。

  2. 無限ループ:

    1. tokenトークンを消費しようとするparserと"char"で実行した結果とする。

    2. もしtokenがnullなら、tokenトークンを消費しようとするparserと"escaped-char"で実行した結果に設定する。

    3. もしtokenがnullなら、break

    4. tokenresultの末尾に追加する。

  3. resultを返す。

保留中の固定値からパートを追加するかもしれないためには、パターンパーサーparserを与える:
  1. もしparser保留中の固定値が空文字列なら、返す。

  2. encoded valueparserエンコーディングコールバックparser保留中の固定値で実行した結果とする。

  3. parser保留中の固定値を空文字列に設定する。

  4. partを新しいパートとして、typeは"fixed-text"、valueencoded valuemodifierは"none"に設定する。

  5. 追加partparserパートリストに追加する。

パートを追加するためには、パターンパーサーparser、文字列prefixトークンname tokenトークンregexp or wildcard token、文字列suffix、およびトークンmodifier tokenを与える:
  1. modifierを"none"とする。

  2. もしmodifier tokenがnullでなければ:

    1. もしmodifier tokenが"?"ならmodifierを"optional"に設定する。

    2. そうでなくmodifier tokenが"*"ならmodifierを"zero-or-more"に設定する。

    3. そうでなくmodifier tokenが"+"ならmodifierを"one-or-more"に設定する。

  3. もしname tokenがnullかつregexp or wildcard tokenがnullかつmodifierが"none"なら:

    これは"{foo}"グループ化です。これを保留中の固定値に追加し、他のテキストと結合します。

    1. parser保留中の固定値の末尾にprefixを追加する。

    2. 返す。

  4. 保留中の固定値からパートを追加するかもしれないparserで実行する。

  5. もしname tokenがnullかつregexp or wildcard tokenがnullなら:

    これは"{foo}?"グループ化です。修飾子があるので、他のテキストと結合できません。直ちにパートとして追加します。

    1. アサートsuffixは空文字列。

    2. もしprefixが空文字列なら、返す。

    3. encoded valueparserエンコーディングコールバックprefixで実行した結果とする。

    4. partを新しいパートとして、typeは"fixed-text"、valueencoded valuemodifiermodifierに設定する。

    5. 追加partparserパートリストに追加する。

    6. 返す。

  6. regexp valueを空文字列とする。

    次にregexp or wildcard tokenを正規表現に変換します。

  7. もしregexp or wildcard tokenがnullなら、regexp valueparserセグメントワイルドカード正規表現に設定する。

  8. そうでなくregexp or wildcard tokentypeが"asterisk"なら、regexp valueフルワイルドカード正規表現値に設定する。

  9. それ以外の場合は、regexp valueregexp or wildcard tokenに設定する。

  10. typeを"regexp"に設定する。

    次にregexp valueパートtypeに変換します。まず正規表現にすることで、"regexp"トークンと"name"や"asterisk"トークンが同様に扱われます。

  11. もしregexp valueparserセグメントワイルドカード正規表現なら:

    1. typeを"segment-wildcard"に設定する。

    2. regexp valueを空文字列に設定する。

  12. そうでなくregexp valueフルワイルドカード正規表現値なら:

    1. typeを"full-wildcard"に設定する。

    2. regexp valueを空文字列に設定する。

  13. nameを空文字列とする。

    次にパートnameを決定します。これは"name"トークンで明示的に指定されるか、自動的に割り当てられます。

  14. もしname tokenがnullでなければ、namename tokenに設定する。

  15. そうでなくregexp or wildcard tokenがnullでなければ:

    1. nameparser次の数値名シリアライズしたものに設定する。

    2. parser次の数値名を1増やす。

  16. もし重複した名前かどうかparsernameで実行した結果がtrueなら、TypeErrorを投げる。

  17. encoded prefixparserエンコーディングコールバックprefixで実行した結果とする。

    最後に固定テキスト値をエンコードし、パートを作成します。

  18. encoded suffixparserエンコーディングコールバックsuffixで実行した結果とする。

  19. partを新しいパートとして、typetypevalueregexp valuemodifiermodifiernamenameprefixencoded prefixsuffixencoded suffixに設定する。

  20. 追加partparserパートリストに追加する。

重複した名前かどうか判定するためには、パターンパーサーparserと文字列nameを与える:
  1. partparserパートリストについて:

    1. もしpartnamenameならtrueを返す。

  2. falseを返す。

2.2. パートリストを正規表現に変換する

正規表現と名前リストを生成するためには、パートリストpart listオプションoptionsを与える:
  1. resultを"^"とする。

  2. name listを新しいリストとする。

  3. partpart listについて:

    1. もしparttypeが"fixed-text"なら:

      1. もしpartmodifierが"none"なら、escape a regexp stringpartvalueで実行した結果をresultの末尾に追加する。

      2. そうでない場合:

        修飾子のある"fixed-text"partは非捕捉グループを使用します。以下の形式になります。

        (?:<固定テキスト>)<修飾子>

        1. resultの末尾に"(?:"を追加する。

        2. escape a regexp stringpartvalueで実行した結果をresultの末尾に追加する。

        3. resultの末尾に")"を追加する。

        4. convert a modifier to a stringpartmodifierで実行した結果をresultの末尾に追加する。

      3. 続行

    2. アサートpartnameが空文字列でない。

    3. 追加partnamename listの末尾に追加する。

      一致グループ名のリストは、互換性のために並行リストで収集します。path-to-regexpと同じ振る舞いを維持するためです。正規表現の名前付きキャプチャグループに変換も可能ですが、アルゴリズムの複雑性からバグのリスクが高く、また生成した正規表現をウェブに公開する場合もpath-to-regexpとの互換性を維持したい意向があります。

    4. regexp valuepartvalueとする。

    5. もしparttypeが"segment-wildcard"なら、regexp valueセグメントワイルドカード正規表現を生成するoptionsで実行した結果に設定する。

    6. そうでなくparttypeが"full-wildcard"なら、regexp valueフルワイルドカード正規表現値に設定する。

    7. もしpartprefixが空文字列であり、かつpartsuffixが空文字列なら:

      プレフィックスやサフィックスがない場合、生成方法は修飾子によって異なります。修飾子がないかoptional修飾子のみの場合は以下の単純な形式を使用します:

      (<regexp value>)<modifier>

      繰り返し修飾子の場合はより複雑な形式になります:

      ((?:<regexp value>)<modifier>)

      1. もしpartmodifierが"none"または"optional"なら:

        1. resultの末尾に"("を追加する。

        2. regexp valueresultの末尾に追加する。

        3. resultの末尾に")"を追加する。

        4. convert a modifier to a stringpartmodifierで実行した結果をresultの末尾に追加する。

      2. そうでない場合:

        1. resultの末尾に"((?:"を追加する。

        2. regexp valueresultの末尾に追加する。

        3. resultの末尾に")"を追加する。

        4. convert a modifier to a stringpartmodifierで実行した結果をresultの末尾に追加する。

        5. resultの末尾に")"を追加する。

      3. 続行

    8. もしpartmodifierが"none" または"optional"なら:

      このセクションは、prefixsuffixがある非繰り返しパートを扱います。内部キャプチャグループで主なregexp valueを含み、外部の非キャプチャグループはプレフィックスやサフィックスと組み合わせます。最終的に修飾子が適用されます。以下の形式となります。

      (?:<prefix>(<regexp value>)<suffix>)<modifier>

      1. resultの末尾に"(?:"を追加する。

      2. escape a regexp stringpartprefixで実行した結果をresultの末尾に追加する。

      3. resultの末尾に"("を追加する。

      4. regexp valueresultの末尾に追加する。

      5. resultの末尾に")"を追加する。

      6. escape a regexp stringpartsuffixで実行した結果をresultの末尾に追加する。

      7. resultの末尾に")"を追加する。

      8. convert a modifier to a stringpartmodifierで実行した結果をresultの末尾に追加する。

      9. 続行

    9. アサートpartmodifierが"zero-or-more"または"one-or-more"である。

    10. アサートpartprefixが空文字列でない、またはpartsuffixが空文字列でない。

      プレフィックスやサフィックスのある繰り返しパートは非常に複雑です。最初のprefixと最後のsuffixは除外し、中間の繰り返し要素間には含みます。これを実現するため、prefixを除外した初期表現を提供し、その後prefix/suffixを含むoptionalな繰り返し要素を追加します。0回許可される場合は、最後にoptional修飾子を付加できます。最終的な形式は以下の通りです。

      (?:<prefix>((?:<regexp value>)(?:<suffix><prefix>(?:<regexp value>))*)<suffix>)?

    11. resultの末尾に"(?:"を追加する。

    12. escape a regexp stringpartprefixで実行した結果をresultの末尾に追加する。

    13. resultの末尾に"((?:"を追加する。

    14. regexp valueresultの末尾に追加する。

    15. resultの末尾に")(?:"を追加する。

    16. escape a regexp stringpartsuffixで実行した結果をresultの末尾に追加する。

    17. escape a regexp stringpartprefixで実行した結果をresultの末尾に追加する。

    18. resultの末尾に"(?:"を追加する。

    19. regexp valueresultの末尾に追加する。

    20. resultの末尾に"))*)"を追加する。

    21. escape a regexp stringpartsuffixで実行した結果をresultの末尾に追加する。

    22. resultの末尾に")"を追加する。

    23. もしpartmodifierが"zero-or-more"なら、resultの末尾に"?"を追加する。

  4. resultの末尾に"$"を追加する。

  5. (result, name list)を返す。

正規表現文字列をエスケープするためには、文字列inputを与える:
  1. アサートinputASCII 文字列である。

  2. resultを空文字列とする。

  3. indexを0とする。

  4. indexinput長さより小さい間:

    1. cinput[index]とする。

    2. indexを1増やす。

    3. もしcが以下のいずれかであれば:

      • U+002E (.);
      • U+002B (+);
      • U+002A (*);
      • U+003F (?);
      • U+005E (^);
      • U+0024 ($);
      • U+007B ({);
      • U+007D (});
      • U+0028 (();
      • U+0029 ());
      • U+005B ([);
      • U+005D (]);
      • U+007C (|);
      • U+002F (/); または
      • U+005C (\),

      なら、resultの末尾に"\"を追加する。

    4. cresultの末尾に追加する。

  5. resultを返す。

2.3. パートリストをパターン文字列に変換する

パターン文字列を生成する ためには、パートリストpart listオプション optionsを与える:
  1. resultを空文字列とする。

  2. index listインデックス取得part listに対して得る。

  3. indexindex listについて:

    1. partpart list[index]とする。

    2. previous partindexが0より大きければpart list[index - 1]、そうでなければnullとする。

    3. next partindexindex listサイズ - 1より小さければpart list[index + 1]、そうでなければnullとする。

    4. もしparttypeが"fixed-text"なら:

      1. もしpartmodifierが"none"なら:

        1. escape a pattern stringpartvalueで実行した結果をresultの末尾に追加する。

        2. 続行

      2. resultの末尾に"{"を追加する。

      3. escape a pattern stringpartvalueで実行した結果をresultの末尾に追加する。

      4. resultの末尾に"}"を追加する。

      5. convert a modifier to a stringpartmodifierで実行した結果をresultの末尾に追加する。

      6. 続行

    5. custom namepartname[0]がASCII数字でなければtrue、そうでなければfalseとする。

    6. needs groupingを以下のいずれかがtrueならtrue、そうでなければfalseとする:

    7. 以下がすべてtrueの場合:

      の場合:
      1. もしnext parttypeが"fixed-text"なら:

        1. is a valid name code pointnext partvalueの最初のコードポイントとfalseで実行した結果がtrueなら、needs groupingをtrueに設定する。

      2. そうでない場合:

        1. next partname[0]がASCII数字なら、needs groupingをtrueに設定する。

    8. 以下がすべてtrueの場合:

      の場合、needs groupingをtrueに設定する。
    9. アサートpartnameが空文字列でもnullでもない。

    10. もしneeds groupingがtrueなら、resultの末尾に"{"を追加する。

    11. escape a pattern stringpartprefixで実行した結果をresultの末尾に追加する。

    12. もしcustom nameがtrueなら:

      1. resultの末尾に":"を追加する。

      2. partnameresultの末尾に追加する。

    13. もしparttypeが"regexp"なら:

      1. resultの末尾に"("を追加する。

      2. partvalueresultの末尾に追加する。

      3. resultの末尾に")"を追加する。

    14. そうでなくparttypeが"segment-wildcard"かつcustom nameがfalseなら:

      1. resultの末尾に"("を追加する。

      2. セグメントワイルドカード正規表現を生成するoptionsで実行した結果をresultの末尾に追加する。

      3. resultの末尾に")"を追加する。

    15. そうでなくparttypeが"full-wildcard"なら:

      1. もしcustom nameがfalseで、以下のいずれかがtrueの場合:

        • previous partがnull
        • previous parttypeが"fixed-text"
        • previous partmodifierが"none"でない
        • needs groupingがtrue
        • partprefixが空文字列でない
        の場合、resultの末尾に"*"を追加する。
      2. そうでない場合:

        1. resultの末尾に"("を追加する。

        2. フルワイルドカード正規表現値resultの末尾に追加する。

        3. resultの末尾に")"を追加する。

    16. 以下がすべてtrueの場合:

      の場合、U+005C (\)をresultの末尾に追加する。
    17. escape a pattern stringpartsuffixで実行した結果をresultの末尾に追加する。

    18. もしneeds groupingがtrueなら、resultの末尾に"}"を追加する。

    19. convert a modifier to a stringpartmodifierで実行した結果をresultの末尾に追加する。

  4. resultを返す。

パターン文字列をエスケープする ためには、文字列inputを与える:
  1. アサートinputASCII 文字列である。

  2. resultを空文字列とする。

  3. indexを0とする。

  4. indexinput長さより小さい間:

    1. cinput[index]とする。

    2. indexを1増やす。

    3. もしcが以下のいずれかであれば:

      • U+002B (+);
      • U+002A (*);
      • U+003F (?);
      • U+003A (:);
      • U+007B ({);
      • U+007D (});
      • U+0028 (();
      • U+0029 ());
      • U+005C (\);

      なら、U+005C (\)をresultの末尾に追加する。

    4. cresultの末尾に追加する。

  5. resultを返す。

修飾子を文字列に変換する ためには、modifiermodifierを与える:
  1. もしmodifierが"zero-or-more"なら、"*"を返す。

  2. もしmodifierが"optional"なら、"?"を返す。

  3. もしmodifierが"one-or-more"なら、"+"を返す。

  4. 空文字列を返す。

3. 正規化

3.1. エンコーディングコールバック

プロトコルを正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. parseResult基本URLパーサーvalue+"://dummy.invalid/"で実行した結果とする。

    ここではstate overrideは使用しません。これはprotocolのsetterにのみ適用される制約を強制するためです。パーサーには通常のエントリポイントを使い、ダミーURLでプロトコルを解析します。

  3. もしparseResultが失敗なら、TypeErrorを投げる。

  4. parseResultschemeを返す。

ユーザー名を正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. dummyURLダミーURL生成で得る。

  3. ユーザー名を設定するdummyURLvalueで実行する。

  4. dummyURLusernameを返す。

パスワードを正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. dummyURLダミーURL生成で得る。

  3. パスワードを設定するdummyURLvalueで実行する。

  4. dummyURLpasswordを返す。

ホスト名を正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. dummyURLダミーURL生成で得る。

  3. parseResult基本URLパーサーvaluedummyURLurlhostname statestate overrideで実行した結果とする。

  4. もしparseResultが失敗なら、TypeErrorを投げる。

  5. dummyURLhost直列化したもの、またはnullなら空文字列を返す。

IPv6ホスト名を正規化するためには、文字列valueを与える:
  1. resultを空文字列とする。

  2. code pointvalueリストとして解釈したコードポイントについて:

    1. 以下がすべてtrueの場合:

      • code pointASCII16進数字でない
      • code pointがU+005B ([)でない
      • code pointがU+005D (])でない
      • code pointがU+003A (:)でない

      なら、TypeErrorを投げる。

    2. ASCII小文字化code pointで実行した結果をresultの末尾に追加する。

  3. resultを返す。

ポートを正規化するためには、文字列portValueおよび省略可能な文字列protocolValueを与える:
  1. もしportValueが空文字列なら、portValueを返す。

  2. dummyURLダミーURL生成で得る。

  3. もしprotocolValueが与えられていれば、dummyURLschemeprotocolValueに設定する。

    これはURLレコードschemeを設定することで、基本URLパーサーがデフォルトポートを認識・正規化できるようにします。

  4. parseResult基本URLパーサーportValuedummyURLurlport statestate overrideで実行した結果とする。

  5. もしparseResultが失敗なら、TypeErrorを投げる。

  6. dummyURLport直列化したもの、またはnullなら空文字列を返す。

パス名を正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. 最初のコードポイントがU+002F (/)ならleading slashをtrue、そうでなければfalseとする。

  3. leading slashがfalseならmodified valueを"/-"、そうでなければ空文字列とする。

    URLパーサーは正規化されたパス名に自動で先頭スラッシュを付与しますが、このアルゴリズムはパス名の部分ごとに呼ばれるため、全体でスラッシュ付与が正しく機能しません。ここでは自前でスラッシュ+文字を挿入し、URLパーサーによるドットの誤解釈を防ぎます。下記でこの挿入文字を削除します。

    実装によっては、URLパーサー自体でスラッシュ付与を無効化しても構いません。

  4. modified valueの末尾にvalueを追加する。

  5. dummyURLダミーURL生成で得る。

  6. 空にするdummyURLpathを空にする。

  7. 基本URLパーサーmodified valuedummyURLurlpath start statestate overrideで実行する。

  8. resultURL path シリアライズdummyURLを実行した結果とする。

  9. leading slashがfalseなら、resultを2文字目以降の部分文字列にする。

  10. resultを返す。

不透明パス名を正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. dummyURLダミーURL生成で得る。

  3. dummyURLpathを空文字列に設定する。

  4. parseResultURLパースvaluedummyURLurlopaque path statestate overrideで実行した結果とする。

  5. もしparseResultが失敗なら、TypeErrorを投げる。

  6. URL path シリアライズdummyURLを実行した結果を返す。

検索部分を正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. dummyURLダミーURL生成で得る。

  3. dummyURLqueryを空文字列に設定する。

  4. 基本URLパーサーvaluedummyURLurlquery statestate overrideで実行する。

  5. dummyURLqueryを返す。

ハッシュを正規化するためには、文字列valueを与える:
  1. もしvalueが空文字列なら、valueを返す。

  2. dummyURLダミーURL生成で得る。

  3. dummyURLfragmentを空文字列に設定する。

  4. 基本URLパーサーvaluedummyURLurlfragment statestate overrideで実行する。

  5. dummyURLfragmentを返す。

3.2. URLPatternInit の処理

URLPatternInitを処理するためには、URLPatternInit init、文字列type、文字列またはnullprotocol、文字列またはnullusername、文字列またはnullpassword、文字列またはnullhostname、文字列またはnullport、文字列またはnullpathname、文字列またはnullsearch、そして文字列またはnullhashを与える:
  1. resultを新しいURLPatternInitとして生成する。

  2. もしprotocolがnullでなければ、設定 result["protocol"] をprotocolにする。

  3. もしusernameがnullでなければ、設定 result["username"] をusernameにする。

  4. もしpasswordがnullでなければ、設定 result["password"] をpasswordにする。

  5. もしhostnameがnullでなければ、設定 result["hostname"] をhostnameにする。

  6. もしportがnullでなければ、設定 result["port"] をportにする。

  7. もしpathnameがnullでなければ、設定 result["pathname"] をpathnameにする。

  8. もしsearchがnullでなければ、設定 result["search"] をsearchにする。

  9. もしhashがnullでなければ、設定 result["hash"] をhashにする。

  10. baseURLをnullとする。

  11. もしinit["baseURL"] が存在する場合:

    base URLは追加の文脈として利用できますが、各コンポーネントについて、initにbase URLのコンポーネントより特定的なものが含まれている場合は継承されません。

    コンポーネントがより特定的であるとは、以下の2つのリストの後ろに現れるほど特定的です(URL構文の順序に近い):

    • protocol, hostname, port, pathname, search, hash

    • protocol, hostname, port, username, password

    ユーザー名とパスワードはURLPattern構築時にはbase URLから継承されません(test()やexec()の引数URLの場合は継承されます)。

    1. baseURL基本URLパーサーinit["baseURL"]を解析した結果に設定する。

    2. もしbaseURLが失敗なら、TypeErrorを投げる。

    3. もしinit["protocol"] が存在しなければ、result["protocol"] をbase URL文字列の処理baseURLschemetypeにより設定する。

    4. もしtypeが"pattern"でなく、initいずれも含まない場合(protocol、hostname、port、username)、result["username"] をbase URL文字列の処理baseURLusernametypeにより設定する。

    5. もしtypeが"pattern"でなく、initいずれも含まない場合(protocol、hostname、port、username、password)、result["password"] をbase URL文字列の処理baseURLpasswordtypeにより設定する。

    6. もしinitprotocolとhostnameを含まない場合:

      1. baseHostを空文字列とする。

      2. もしbaseURLhostがnullでなければ、それを直列化してbaseHostに設定する。

      3. result["hostname"] をbase URL文字列の処理baseHosttypeにより設定する。

    7. もしinitprotocol、hostname、portを含まない場合:

      1. もしbaseURLportがnullであれば、result["port"] を空文字列に設定する。

      2. そうでなければ、result["port"] をbaseURLport直列化に設定する。

    8. もしinitprotocol、hostname、port、pathnameを含まない場合、result["pathname"] をbase URL文字列の処理URL pathシリアライズしたbaseURLtypeで設定する。

    9. もしinitprotocol、hostname、port、pathname、searchを含まない場合:

      1. baseQuerybaseURLqueryに設定する。

      2. もしbaseQueryがnullなら、空文字列にする。

      3. result["search"] をbase URL文字列の処理baseQuerytypeで設定する。

    10. もしinitprotocol、hostname、port、pathname、search、hashを含まない場合:

      1. baseFragmentbaseURLfragmentに設定する。

      2. もしbaseFragmentがnullなら、空文字列にする。

      3. result["hash"] をbase URL文字列の処理baseFragmenttypeで設定する。

  12. もしinit["protocol"] が存在するなら、result["protocol"] をprocess protocol for initinit["protocol"]とtypeにより設定する。

  13. もしinit["username"] が存在するなら、result["username"] をprocess username for initinit["username"]とtypeにより設定する。

  14. もしinit["password"] が存在するなら、result["password"] をprocess password for initinit["password"]とtypeにより設定する。

  15. もしinit["hostname"] が存在するなら、result["hostname"] をprocess hostname for initinit["hostname"]とtypeにより設定する。

  16. resultProtocolStringresult["protocol"]が存在すればそれに、なければ空文字列とする。

  17. もしinit["port"] が存在するなら、result["port"] をprocess port for initinit["port"]、resultProtocolStringtypeにより設定する。

  18. もしinit["pathname"] が存在する場合:

    1. result["pathname"] をinit["pathname"]に設定する。

    2. 以下がすべてtrueの場合:

      の場合:

      1. baseURLPathbase URL文字列の処理URL pathシリアライズしたbaseURLtypeの結果に設定する。

      2. slash indexbaseURLPath内の最後のU+002F (/)コードポイントのインデックス(なければnull)とする。

      3. もしslash indexがnullでなければ:

        1. new pathnamebaseURLPathの0からslash index+1までの部分文字列に設定する。

        2. result["pathname"]の値をnew pathnameの末尾に追加する。

        3. result["pathname"]をnew pathnameに設定する。

    3. result["pathname"] をprocess pathname for initresult["pathname"]、resultProtocolStringtypeにより設定する。

  19. もしinit["search"] が存在するなら、result["search"] をprocess search for initinit["search"]とtypeにより設定する。

  20. もしinit["hash"] が存在するなら、result["hash"] をprocess hash for initinit["hash"]とtypeにより設定する。

  21. resultを返す。

base URL文字列の処理ためには、文字列inputと文字列typeを与える:
  1. アサートinputはnullでない。

  2. もしtypeが"pattern"でなければinputを返す。

  3. パターン文字列をエスケープするinputで実行した結果を返す。

絶対パス名か判定するためには、pattern stringinputと文字列typeを与える:
  1. もしinputが空文字列ならfalseを返す。

  2. もしinput[0]がU+002F (/)ならtrueを返す。

  3. もしtypeが"url"ならfalseを返す。

  4. もしinputコードポイント長が2未満ならfalseを返す。

  5. もしinput[0]がU+005C (\)でinput[1]がU+002F (/)ならtrueを返す。

  6. もしinput[0]がU+007B ({)でinput[1]がU+002F (/)ならtrueを返す。

  7. falseを返す。

process protocol for initためには、文字列valueと文字列typeを与える:
  1. strippedValueを与えられたvalueから末尾のU+003A (:)を1つ削除したものとする。

  2. もしtypeが"pattern"ならstrippedValueを返す。

  3. プロトコルを正規化するstrippedValueで実行した結果を返す。

process username for initためには、文字列valueと文字列typeを与える:
  1. もしtypeが"pattern"ならvalueを返す。

  2. ユーザー名を正規化するvalueで実行した結果を返す。

process password for initためには、文字列valueと文字列typeを与える:
  1. もしtypeが"pattern"ならvalueを返す。

  2. パスワードを正規化するvalueで実行した結果を返す。

process hostname for initためには、文字列valueと文字列typeを与える:
  1. もしtypeが"pattern"ならvalueを返す。

  2. ホスト名を正規化するvalueで実行した結果を返す。

process port for initためには、文字列portValue、文字列protocolValue、文字列typeを与える:
  1. もしtypeが"pattern"ならportValueを返す。

  2. ポートを正規化するportValueprotocolValueで実行した結果を返す。

process pathname for initためには、文字列pathnameValue、文字列protocolValue、文字列typeを与える:
  1. もしtypeが"pattern"ならpathnameValueを返す。

  2. もしprotocolValue特別なスキームまたは空文字列なら、パス名を正規化するpathnameValueで実行した結果を返す。

    protocolValueが空文字列の場合は、constructor dictionaryでprotocolが指定されていないことを示します。通常は空文字列の特別扱いはしませんが、この場合は最も一般的なパス名正規化に合わせ特別なスキームとして扱います。

  3. 不透明パス名を正規化するpathnameValueで実行した結果を返す。

process search for initためには、文字列valueと文字列typeを与える:
  1. strippedValueを与えられたvalueから先頭のU+003F (?)を1つ削除したものとする。

  2. もしtypeが"pattern"ならstrippedValueを返す。

  3. 検索部分を正規化するstrippedValueで実行した結果を返す。

process hash for initためには、文字列valueと文字列typeを与える:
  1. strippedValueを与えられたvalueから先頭のU+0023 (#)を1つ削除したものとする。

  2. もしtypeが"pattern"ならstrippedValueを返す。

  3. ハッシュを正規化するstrippedValueで実行した結果を返す。

4. 他の仕様におけるURLパターンの利用

ウェブプラットフォームにおける一貫性を促進するため、他の文書が本仕様と統合される場合は、特別な理由がない限り下記のガイドラインに従うべきです。

  1. 省略記法を許容する。ほとんどの著者パターンは単純かつ直接的です。したがって、APIはこれら一般的なケースについて省略記法を受け入れ、著者が完全なURLPattern オブジェクトへ変換するための追加作業を不要にすべきです。

  2. ベースURLを尊重する。URLは通常、その環境のベースURL(多くの場合、ドキュメントのベースURL)に相対して解析されますが、URLパターンも同様にこれを尊重すべきです。URLPattern のコンストラクタは例外であり、直接コンセプトを公開します。これはURLコンストラクタがベースURLを尊重しないのと同様です。

  3. 正規表現グループについて明確にする。一部のAPIでは、正規表現グループを含まないURLパターンのみを許容する方が有益です。たとえば、ユーザーエージェントが著者スクリプトを実行するスレッドやプロセスと異なる場所で実装することが予想される場合や、セキュリティ・パフォーマンスの観点からJavaScriptエンジンが通常は動作しない場合などです。この場合は、(has regexp groupsへの参照付きで)明示的に文書化し、なるべく早い段階(例:JavaScript例外を投げるなど)でエラーを報告すべきです。可能ならば、将来的な制約解除のためにフィーチャ検出可能にしてください。URLパターンの異なるサブセットを作成する際は、本仕様のエディターに相談してください。

  4. どのURLがマッチするかを明確にする。例えば、フェッチ処理中のアルゴリズムはフラグメントのないURLを扱う場合が多いです。その場合、仕様はその旨を明示すべきで、マッチしないパターン(例:非空フラグメントを要求するなど)が使われた際に開発者警告を表示することを推奨する場合があります。

4.1. JavaScript APIとの統合

typedef (USVString or URLPatternInit or URLPattern) URLPatternCompatible;

JavaScript APIは以下すべてを受け入れるべきです:

これを達成するため、仕様はURLPatternCompatibleoperationdictionary memberの引数として受け付け、下記のアルゴリズムに従い、適切な環境設定オブジェクトAPIベースURL等を利用してください。

URLPattern オブジェクトをWeb IDL値から構築するためには、URLPatternCompatible inputURLbaseURLrealmrealmを与え、次の手順を実行する:
  1. もしinput特定型URLPatternなら:

    1. inputを返す。

  2. それ以外の場合:

    1. patternrealm新しいURLPattern とする。

    2. pattern関連URLパターンを、Web IDL値からURLパターンを構築するinputbaseURLを渡した結果に設定する。

    3. patternを返す。

Web IDL値からURLパターンを構築するためには、URLPatternCompatible inputURLbaseURLを与え、次の手順を実行する:
  1. もしinput特定型URLPatternなら:

    1. input関連URLパターンを返す。

  2. それ以外でinput特定型URLPatternInitなら:

    1. initinputクローンとする。

    2. もしinit["baseURL"] が存在しなければ、baseURL直列化で設定する。

    3. URLパターン構築init、null、空のmapの結果を返す。

  3. それ以外:

    1. アサートinput特定型USVStringである。

    2. URLパターン構築inputbaseURL直列化、空のmapの結果を返す。

このようにして、著者はほとんどのパターンを簡潔に指定でき、必要であればコンストラクタを使って非一般的なオプションにもアクセスできます。ベースURLの暗黙的利用はHTMLURLの解析アルゴリズムと類似しており、現行標準の一貫性があります。[HTML]

4.2. JSONデータ形式との統合

URLパターンを含むJSONデータ形式では、JavaScript APIの振る舞いに倣い、以下の両方を受け入れるべきです:

仕様がInfra値(例:JSON文字列をInfra値へ解析後)を持つ場合は、適切なベースURL(通常はJSONリソースのURL)を使い、以下のアルゴリズムを使用してください。[INFRA]

Infra値からURLパターンを構築するためには、rawPatternURL baseURLを与え、次の手順を実行してください。
  1. serializedBaseURLbaseURL直列化とする。

  2. もしrawPattern文字列なら:

    1. URLパターン構築rawPatternserializedBaseURL、空のmapの結果を返す。

      将来的には非空のオプションを追加する必要が出るかもしれません。
  3. それ以外でrawPatternmapなら:

    1. initを «[ "baseURL" → serializedBaseURL ]»(URLPatternInit型の辞書)とする。

    2. keyvaluerawPatternについて:

      1. もしkeyURLPatternInit識別子でも継承辞書の識別子でもなく、かつvalue文字列でなく、またそのメンバー型がUSVStringでなければ、nullを返す。

        今後URLPatternInitに他型のメンバーが追加された場合は更新が必要です。
        将来、より緩いモードも有用なら導入される可能性があります。
      2. init[key]をvalueに設定する。

    3. URLパターン構築init、null、空のmapの結果を返す。

      将来的には非空のオプションを追加する必要が出るかもしれません。
  4. それ以外の場合はnullを返す。

仕様は、URLPatternOptionsのオプション受け入れやベースURLの上書きなどを許容できる余地を残しておくべきです。JSON APIの場合はURLPatternオブジェクトを直接構築できないためです。例えばSpeculation Rulesでは、"relative_to"キーによりJSONリソースのURLの代わりにドキュメントのベースURLを利用できます。[SPECULATION-RULES]

4.3. HTTPヘッダーフィールドとの統合

URLパターンを含むHTTPヘッダーは、コンストラクタ文字列構文による文字列を受け入れるべきです(構造化フィールドの一部として)。[RFC9651]

現状、URLパターンに辞書構文を受け入れるヘッダーは存在しません。もし変更があれば、本仕様で[RFC9651]の内部リスト処理方法を定義予定です。

HTTPヘッダー仕様では、URLパターン(例:matchアルゴリズム)を使うべきであり、JavaScriptrealmを暗示するURLPatternオブジェクトは使うべきではありません。

HTTP構造化フィールド値からURLパターンを構築するためには、rawPatternURLbaseURLを与え:
  1. serializedBaseURLbaseURL直列化とする。

  2. アサートrawPattern文字列である。

  3. URLパターン構築rawPatternserializedBaseURL、空のmapの結果を返す。

仕様によっては、評価対象パターンに正規表現グループを含まないもののみを受け入れることも検討できます。これは、そのようなパターンの方がパフォーマンスが安定し、[ECMA-262]の正規表現実装を不要とし、セキュリティ・コードサイズ・実装負荷などにメリットがあるためです。一方、JavaScript APIはそのような実装が容易な環境で動作します。

謝辞

編集者は次の方々に感謝します: Alex Russell、 Anne van Kesteren、 Asa Kusuma、 Blake Embrey、 Cyrus Kasaaian、 Daniel Murphy、 Darwin Huang、 Devlin Cronin、 Domenic Denicola、 Dominick Ng、 Jake Archibald、 Jeffrey Posnick、 Jeremy Roman、 Jimmy Shen、 Joe Gregorio、 Joshua Bell、 石橋健一(Kenichi Ishibashi)、 Kenji Baheux、 Kenneth Rohde Christiansen、 Kingsley Ngan、 Kinuko Yasuda、 L. David Baron、 Luca Casonato、 Łukasz Anforowicz、 島津誠(Makoto Shimazu)、 Marijn Kruisselbrink、 Matt Falkenhagen、 Matt Giuca、 Michael Landry、 R. Samuel Klatchko、 Rajesh Jagannathan、 Ralph Chelala、 Sangwhan Moon、 Sayan Pal、 Victor Costan、 柳沢義智(Yoshisato Yanagisawa)、および Youenn Fablet ―本仕様への貢献に対して。

特に、Blake Embrey 氏および他の pillarjs/path-to-regexp コントリビューターに感謝します。多くの人々に役立つ素晴らしいオープンソースライブラリを構築してくださいました。

また、Kenneth Rohde Christiansen 氏の polyfill の作業にも特別な感謝を表します。彼は変化する URLPattern API に適応するため、多大な労力を費やしました。

本標準は、 Ben Kelly (Google, wanderview@chromium.org)、 Jeremy Roman (Google, jbroman@chromium.org)、および 宍戸俊哉(Shunya Shishido, Google, sisidovski@chromium.org) によって執筆されています。

知的財産権

この現行標準は元々 W3C WICG にて開発され、W3C ソフトウェア及びドキュメントライセンスのもとで公開されていました。

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft)。この著作物は クリエイティブ・コモンズ 表示 4.0 国際ライセンスのもとでライセンスされています。その一部がソースコードに組み込まれる場合、ソースコード部分はBSD 3-Clause ライセンスのもとでライセンスされます。

これは現行標準です。 特許審査版に関心のある方は現行標準レビュー草案をご覧ください。

索引

本仕様で定義されている用語

参照によって定義される用語

参考文献

規定参考文献

[ECMA-262]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[HTML]
Anne van Kesteren; et al. HTML Standard. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 現行標準. URL: https://infra.spec.whatwg.org/
[RFC9651]
M. Nottingham; P-H. Kamp. Structured Field Values for HTTP. 2024年9月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc9651
[URL]
Anne van Kesteren. URL Standard. 現行標準. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 現行標準. URL: https://webidl.spec.whatwg.org/

参考情報文献

[SPECULATION-RULES]
Speculation Rules. Draft Community Group Report. URL: https://wicg.github.io/nav-speculation/speculation-rules.html

IDL索引

typedef (USVString or URLPatternInit) URLPatternInput;

[Exposed=(Window,Worker)]
interface URLPattern {
  constructor(URLPatternInput input, USVString baseURL, optional URLPatternOptions options = {});
  constructor(optional URLPatternInput input = {}, optional URLPatternOptions options = {});

  boolean test(optional URLPatternInput input = {}, optional USVString baseURL);

  URLPatternResult? exec(optional URLPatternInput input = {}, optional USVString baseURL);

  readonly attribute USVString protocol;
  readonly attribute USVString username;
  readonly attribute USVString password;
  readonly attribute USVString hostname;
  readonly attribute USVString port;
  readonly attribute USVString pathname;
  readonly attribute USVString search;
  readonly attribute USVString hash;

  readonly attribute boolean hasRegExpGroups;
};

dictionary URLPatternInit {
  USVString protocol;
  USVString username;
  USVString password;
  USVString hostname;
  USVString port;
  USVString pathname;
  USVString search;
  USVString hash;
  USVString baseURL;
};

dictionary URLPatternOptions {
  boolean ignoreCase = false;
};

dictionary URLPatternResult {
  sequence<URLPatternInput> inputs;

  URLPatternComponentResult protocol;
  URLPatternComponentResult username;
  URLPatternComponentResult password;
  URLPatternComponentResult hostname;
  URLPatternComponentResult port;
  URLPatternComponentResult pathname;
  URLPatternComponentResult search;
  URLPatternComponentResult hash;
};

dictionary URLPatternComponentResult {
  USVString input;
  record<USVString, (USVString or undefined)> groups;
};

typedef (USVString or URLPatternInit or URLPattern) URLPatternCompatible;

MDN

URLPattern/URLPattern

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/exec

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/hash

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/hostname

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/password

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/pathname

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/port

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/protocol

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/search

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/test

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern/username

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

URLPattern

In only one current engine.

FirefoxNoneSafariNoneChrome95+
Opera?Edge95+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?