Вот расширенная версия привязанных Andy E строк «Обработка строк в стиле массива» -версия. Исправлена ошибка (?key=1&key[]=2&key[]=3
; 1
теряется и заменяется на [2,3]
), сделал несколько незначительных улучшений производительности (повторное декодирование значений, пересчет «[» и т. Д.) И добавил ряд улучшений ( функционализация, поддержка ?key=1&key=2
, поддержка разделителей ;
). Я оставил переменные досадно короткими, но добавил комментарии в изобилии, чтобы сделать их доступными для чтения (о, и я повторно использовал v
в локальных функциях, извините, если это запутывает;).
Он будет обрабатывать следующую последовательность запросов ...
? test = Hello & amp; person = neek & amp; person [] = jeff & amp; person [] = jim & amp; person [extra] = john & amp; test3 & amp; nocache = 1398914891264
... превращая его в объект, который выглядит как ...
{ "test": "Hello", "person": { "0": "neek", "1": "jeff", "2": "jim", "length": 3, "extra": "john" }, "test3": "", "nocache": "1398914891264" }
Как вы можете видеть выше, эта версия обрабатывает некоторую меру «искаженных» массивов, т. е.
person=neek&person[]=jeff&person[]=jim
илиperson=neek&person=jeff&person=jim
, поскольку ключ идентифицируется и действителен (по крайней мере, в dotNet's NameValueCollection.Add ):Если указанный ключ уже существует в целевом Экземпляр NameValueCollection, указанное значение добавляется к существующему списку значений, разделенных запятыми, в форме «value1, value2, value3».
Кажется, жюри несколько вышло на повторных клавишах, поскольку спецификация отсутствует. В этом случае несколько ключей сохраняются как (поддельный) массив. Но обратите внимание, что я не обрабатываю значения на основе запятых в массивах.
Код:
getQueryStringKey = function(key) { return getQueryStringAsObject()[key]; }; getQueryStringAsObject = function() { var b, cv, e, k, ma, sk, v, r = {}, d = function (v) { return decodeURIComponent(v).replace(/\+/g, " "); }, //# d(ecode) the v(alue) q = window.location.search.substring(1), //# suggested: q = decodeURIComponent(window.location.search.substring(1)), s = /([^&;=]+)=?([^&;]*)/g //# original regex that does not allow for ; as a delimiter: /([^&=]+)=?([^&]*)/g ; //# ma(make array) out of the v(alue) ma = function(v) { //# If the passed v(alue) hasn't been setup as an object if (typeof v != "object") { //# Grab the cv(current value) then setup the v(alue) as an object cv = v; v = {}; v.length = 0; //# If there was a cv(current value), .push it into the new v(alue)'s array //# NOTE: This may or may not be 100% logical to do... but it's better than loosing the original value if (cv) { Array.prototype.push.call(v, cv); } } return v; }; //# While we still have key-value e(ntries) from the q(uerystring) via the s(earch regex)... while (e = s.exec(q)) { //# while((e = s.exec(q)) !== null) { //# Collect the open b(racket) location (if any) then set the d(ecoded) v(alue) from the above split key-value e(ntry) b = e[1].indexOf("["); v = d(e[2]); //# As long as this is NOT a hash[]-style key-value e(ntry) if (b < 0) { //# b == "-1" //# d(ecode) the simple k(ey) k = d(e[1]); //# If the k(ey) already exists if (r[k]) { //# ma(make array) out of the k(ey) then .push the v(alue) into the k(ey)'s array in the r(eturn value) r[k] = ma(r[k]); Array.prototype.push.call(r[k], v); } //# Else this is a new k(ey), so just add the k(ey)/v(alue) into the r(eturn value) else { r[k] = v; } } //# Else we've got ourselves a hash[]-style key-value e(ntry) else { //# Collect the d(ecoded) k(ey) and the d(ecoded) sk(sub-key) based on the b(racket) locations k = d(e[1].slice(0, b)); sk = d(e[1].slice(b + 1, e[1].indexOf("]", b))); //# ma(make array) out of the k(ey) r[k] = ma(r[k]); //# If we have a sk(sub-key), plug the v(alue) into it if (sk) { r[k][sk] = v; } //# Else .push the v(alue) into the k(ey)'s array else { Array.prototype.push.call(r[k], v); } } } //# Return the r(eturn value) return r; };