HTTP Accept ヘッダーを解析して、そこからすべての詳細を抽出しようとしています。私は次の仮定をしています:
各エントリは、少なくとも で始まり、少なくとも を含む必要があります。type/subtype
オプションで、+basetype
たとえばtext/html
またはapplication/xhtml+xml
エントリはコンマで区切られます。最初の の後type/subtype
に、エントリには、セミコロンで区切られた可変数のパラメータkey=value
ペアを含めることができます (セミコロン間では空白を使用できますが、ペア間=
では空白を使用できませんkey=value
)。たとえば、application/xhtml+xml; q=0.8; test=hello
このすべての情報を配列に取得したいと考えています。
私が現在持っているのはpreg_match_all('/([^,;\/=\s]+)\/([^,;\/=\s+]+)(\+([^,;\/=\s+]+))?(\s?;\s?([^,;=]+)=([^,;=]+))*/', $header, $result, PREG_SET_ORDER);
、私の考えでは、タイプの最初のキャプチャグループ、次にサブタイプのキャプチャグループ、次にベースタイプのオプションのグループ、次に で区切られたオプションの繰り返しグループを提供するもので;
、2つを含みますkey=value
。
ヘッダー文字列で使用すると、次のようになりapplication/xhtml+xml; q=0.9; level=3 , text/html,application/json;test=hello
ます。
Array
(
[0] => Array
(
[0] => application/xhtml+xml; q=0.9; level=3
[1] => application
[2] => xhtml
[3] => +xml
[4] => xml
[5] => ; level=3
[6] => level
[7] => 3
)
[1] => Array
(
[0] => text/html
[1] => text
[2] => html
)
[2] => Array
(
[0] => application/json;test=hello
[1] => application
[2] => json
[3] =>
[4] =>
[5] => ;test=hello
[6] => test
[7] => hello
)
)
key=value
これは問題ありませんが、最初のエントリ ( application/xhtml+xml; q=0.9; level=3
)に対して最後のみが指定され、q=0.9
がありません。
正規表現を 1 つだけ使用しながら、各一致にすべての (可変数の) パラメータを含める方法はありますか、またはkey=value
ペアに別の正規表現/関数を使用する必要がありますか?
編集:
私が望む配列結果の種類は次のとおりです(明らかに、各コンテンツタイプのアイテム0、3、5、8などは不要ですが、除外できるかどうかはわかりません):
Array
(
[0] => Array
(
[0] => application/xhtml+xml; q=0.9; level=3
[1] => application
[2] => xhtml
[3] => +xml
[4] => xml
[5] => ; q=0.9
[6] => q
[7] => 0.9
[8] => ; level=3
[9] => level
[10] => 3
)
[1] => Array
(
[0] => text/html
[1] => text
[2] => html
)
[2] => Array
(
[0] => application/json;test=hello
[1] => application
[2] => json
[3] =>
[4] =>
[5] => ;test=hello
[6] => test
[7] => hello
)
)
これにより、さらに正規表現や文字列関数を実行しなくても、各パラメーターのキーと値を取得できます。
編集
Kaの回答を受け入れました。必要なものはすべて揃っているようです。彼のパターン(?:\G\s?,\s?|^)(\w+)\/(\w+)(?:\+(\w+))?|(?<!^)\G(?:\s?;\s?(\w+)=([\w\.]+))
を同じ文字列で (設定された順序なしで) 使用すると、次の結果が得られます。
Array
(
[0] => Array
(
[0] => application/xhtml+xml
[1] => ; q=0.9
[2] => ; level=3
[3] => , text/html
[4] => ,application/json
[5] => ;test=hello
)
[1] => Array
(
[0] => application
[1] =>
[2] =>
[3] => text
[4] => application
[5] =>
)
[2] => Array
(
[0] => xhtml
[1] =>
[2] =>
[3] => html
[4] => json
[5] =>
)
[3] => Array
(
[0] => xml
[1] =>
[2] =>
[3] =>
[4] =>
[5] =>
)
[4] => Array
(
[0] =>
[1] => q
[2] => level
[3] =>
[4] =>
[5] => test
)
[5] => Array
(
[0] =>
[1] => 0.9
[2] => 3
[3] =>
[4] =>
[5] => hello
)
)
ここから、インデックス 1 の配列を使用して連想配列をコンパイルし、個々のコンテンツ タイプとそのパラメーターの境界を判断できます。
Ka の助けに感謝します。
編集:
式を再度変更しました。式は、text/*
. したがって、式は次のようになります。
(?:\G\s?,\s?|^)(\w+|\*)\/(\w+|\*)(?:\+(\w+))?|(?<!^)\G(?:\s?;\s?(\w+)=([\w\.]+))