我正在尝试解析 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);
,在我看来,它给出了一个带有类型的初始捕获组,然后是一个带有子类型的捕获组,然后是一个带有基本类型的可选捕获组,然后是一个可选的重复捕获组,由 分隔;
,其中包含两个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
缺少 。
有什么方法可以在每个匹配项中包含所有(可变数量)参数,同时仍然只使用一个正则表达式,还是我必须为这些对使用单独的正则表达式/函数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 的帮助。
编辑:
再次更改了表达式 - 表达式还需要能够解析通配符 mime,例如text/*
. 所以现在的表达式变成了:
(?:\G\s?,\s?|^)(\w+|\*)\/(\w+|\*)(?:\+(\w+))?|(?<!^)\G(?:\s?;\s?(\w+)=([\w\.]+))