首页 > 试题广场 >

获取 url 参数

[编程题]获取 url 参数
  • 热度指数:92244 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
获取 url 中的参数
1. 指定参数名称,返回该参数的值 或者 空字符串
2. 不指定参数名称,返回全部的参数对象 或者 {}
3. 如果存在多个同名参数,则返回数组
4. 不支持URLSearchParams方法
示例1

输入

http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe key

输出

[1, 2, 3]
function getUrlParam(sUrl, sKey) {
    var res = {};
    sUrlNew = sUrl.split("?")[1];
    sUrlNew.replace(/(\w+)=(\w+)&?/g,function(item0,item1,item2){
        res[item1] = (res[item1] == undefined)? item2 : [].concat(res[item1], item2);
    });
    if(sKey){
        return res[sKey] || "";
    }
    return res;
}

发表于 2016-10-15 12:51:00 回复(0)
更多回答
大家都在用replace,其实RegExp对象中有个用于执行模式匹配操作的方法更好用,就是exec(), exec()有个特殊的性质,当正则表达式具有全局标记g时,仍然时返回一个匹配及分组匹配的子串,当再次调用exec()时,它会从lastIndex属性所指示的字符处开始检索,基exec()自带遍历功能,代码如下:
function getUrlParam(sUrl, sKey) {
   var r=/(\?|&)(\w+)\=(\w+)/g;
   var res={};
   while(r.exec(sUrl)!=null){
       if(res[RegExp.$2]){
           var temp=res[RegExp.$2];
           res[RegExp.$2]=[].concat(temp,RegExp.$3)
       }else{
           res[RegExp.$2]=RegExp.$3;
       }
   }
   if(sKey) {
       return res[sKey]||'';
   }
   return res;
}

发表于 2017-03-21 22:12:41 回复(6)
function getUrlParam(sUrl, sKey) {
    var paramsN = sUrl.split("?")[1];//取出url后的字符串
    var params = paramsN.split("#")[0];//剔除字符串#后的杂质
    var param = params.split("&");//将字符串分割为键值对为一项的数组
    var arr = [];

    if(sKey){//如果有参数
        for(var i = 0;i<param.length;i++){//遍历键值对数组
            var keyV = param[i].split("=");//分开键和值
            if(keyV[0] === sKey){//如果有和传入的参数一样的键,则将其值插入到空数组中
                arr.push(keyV[1]);
            }
        }
        if(arr.length === 0){//如果数组仍为空,则证明没有传入的参数的值
            return "";
        }else if(arr.length > 1){//有多个值
            return arr;
        }else{//只有一个值
            return arr[0];
        }
    }else{//没有传入参数,返回对象
        var obj = {};
        for(var i = 0;i<param.length;i++){//遍历
            var keyV = param[i].split("=");//分开键和值
            if(obj[keyV[0]]){//如果对象中有该属性
                obj[keyV[0]].push(keyV[1])//插入该属性中的数组中
            }else{
                obj[keyV[0]] = [keyV[1]]//如果没有则创建一个数组并且把值放入该数组中
            }
        }
        for(var key in obj){//遍历插入数据的对象
            if(obj[key].length === 1){//如果该对象的属性值的数组的长度为一
                obj[key] = obj[key][0]//则让该对象的该属性值为数组里的值
            }
        }
        return obj;
    }
}

发表于 2019-09-20 14:29:45 回复(3)
//参考大神的方法
function getUrlParam(sUrl, sKey) {
    var result,Oparam = {};
    sUrl.replace(/[\?|&]?(\w+)=(\w+)/g,function($0,$1,$2){
        Oparam[$1] === void 0 ? Oparam[$1]=$2 : Oparam[$1]=[].concat(Oparam[$1],$2);
    });
    sKey === void 0||sKey==='' ? result=Oparam : result=Oparam[sKey]||'';
    return result;
}
//不用正则表达式的方法
function getUrlParam(sUrl, sKey) {
    var psArr = /\?/.test(sUrl) ? sUrl.split('?')[1].split('#')[0].split('&') : [];
    var result,Oparam = {};
    for(var i=0;i<psArr.length;i++){
        var pA = psArr[i].split('=');
        Oparam[pA[0]] === void 0 ? Oparam[pA[0]]=pA[1] : Oparam[pA[0]]=[].concat(Oparam[pA[0]],pA[1]);
    }
    sKey === void 0||sKey==='' ? result=Oparam : result=Oparam[sKey]||'';
    return result;
}

编辑于 2016-08-26 22:22:34 回复(0)
function getUrlParam(sUrl, sKey) {
    var resObj = {};
    var reg = /(\w+)=(\w+)/g;
    while (reg.exec(sUrl)) {
        resObj[RegExp.$1] ? resObj[RegExp.$1] = [].concat(resObj[RegExp.$1], RegExp.$2) : resObj[RegExp.$1] = RegExp.$2;
    }

    if (sKey) {
        return (resObj[sKey] ? resObj[sKey] : '');
    }
    return resObj;
}
有点坑啊,不能用ES6语法,用了let结果怎么也不通过,调试了接近20分钟。。。醉。。。
编辑于 2017-08-30 09:02:57 回复(2)
宝贝们记住一定不要用ES6语法!!!!!不要用let!!!!!!!!!记住了!!!!!!!!!!!!!!!!我突然想起之前好多次在牛客网做题都通不过,可能就是因为let!!!!!!!!!
发表于 2018-03-17 11:17:06 回复(4)
function getUrlParam(_url, name) {
    let us=_url.split('?')[1].split('&')
    //指定参数
    if(name){
        let arr=[]
        if(us.filter(item=>item.split('=')[0]==name).length>1){
           us.map(item=>{
                let str=item.split('=')
               if(str[0]==name){
                   arr.push(str[1])
               }
           })
            return arr
        }else{
          let _name = name.replace(/(?=[\\^$*+?.():|{}])/, '\\')
          let reg = new RegExp('(?:[?&]|^)' + _name + '=([^?&#]*)', 'i')
          let match = _url.match(reg)
          return !match ? '' : match[1]
        }
    }else{
        if(us.length<=0){
            return {}
        }else{
            let obj={}
            us.map(item=>{
                let str=item.split('=')
                if(obj.hasOwnProperty(str[0])){
                    obj[str[0]].push(str[1])
                }else{
                    obj[str[0]]=[str[1]]
                }
            })
            return obj
        }
    }
}

发表于 2020-10-25 23:19:52 回复(0)
function getUrlParam(sUrl, sKey) {
    var result = {}
    sUrl.replace(/\??(\w+)=(\w+)&?/g, function(a, k, v){
        result[k] = result[k]? [...result[k]].concat(v) : v
    })
    return sKey? result[sKey]? result[sKey] : '' : result
}

发表于 2020-07-21 11:59:28 回复(0)
1. 使用 split 分割 # 前的 path ,因为虽然也能用正则去匹配 # 前的字符串,但是提高了正则的复杂性,降低正则的执行效率;
2. key 不能为空, value 可以为空但不能包含 & 或 # ;
3. 因为函数无副作用,假定 sUrl 总为字符串的前提下,可以直接根据有没有 .push() 方法来判断数组;
4. JS 的 || 短路还是很好用的,没必要条件表达式了。
function getUrlParam(sUrl, sKey) {
    var paramsMap = {};
    var path = sUrl.split('#', 1)[0];
    path.replace(/(\w+)=([^&#]*)/g, function (item, key, value) {
        var prev = paramsMap[key];
        if (undefined === prev) {
            paramsMap[key] = value;
        } else if (undefined === prev.push) {
            paramsMap[key] = [prev, value];
        } else {
            paramsMap[key].push(value);
        }
    });
    return undefined === sKey
        ? paramsMap
        : (paramsMap[sKey] || '');
}

编辑于 2018-08-25 18:24:43 回复(1)
//正则表达式
function getUrlParam(sUrl, sKey) {
    var obj = {};
    var reg = /[?&](\w+)=(\w+)/g;
    while(reg.exec(sUrl))
        obj[RegExp.$1] ? obj[RegExp.$1]=[].concat(obj[RegExp.$1],RegExp.$2) : obj[RegExp.$1]=RegExp.$2; 
    return sKey ? obj[sKey]||"" : obj;
}

发表于 2017-08-09 21:32:03 回复(0)
// By ClayIdol
function getUrlParam(sUrl, sKey) {
    
    var r = [] , s = null  , i = 0;
    var regexp = new RegExp(/[?&]([\w]*)=([^&#]*)/g);
    
    while((s = regexp.exec(sUrl)) != null){
         if(!r[s[1]])r[s[1]] = s[2];
         else if(typeof(r[s[1]]) == 'object'){
             r[s[1]].push(s[2]);
         }else{
              r[s[1]] = [r[s[1]],s[2]];
         }
    }
    if(sKey){
        //有参数,返回参数值或空
        if(r[sKey]){
            return r[sKey];
        }else{
            return '';
        }
    }else{
        return r;
    }
}

编辑于 2015-07-02 09:30:10 回复(2)
function getUrlParam(sUrl, sKey) {
    const s = sUrl.split('?')[1].split('#')[0].split('&')
    const map = {}
    s.forEach(item => {
        const [key, val] = item.split('=')
        if (map[key] === undefined) map[key] = val
        else if (typeof map[key] === 'string') map[key] = [map[key], val]
        else map[key].push(val)
    })
    if (!sKey) return map
    return map[sKey] || ''
}

发表于 2021-11-26 16:30:52 回复(0)
function getUrlParam(sUrl, sKey) {
    //正则表达式匹配key=value
            var re = /(\w+)=(\w+)/g;
            var arr = sUrl.match(re);
            var item = {};
    //判断有没有传参数
            var key = sKey || false;
            var key1;
    //如果有相同的参数名,flag会变成true
            var flag = false;
            for (var i = 0; i < arr.length; i++) {
                //键
                var item1 = arr[i].split('=')[0];
                //值
                var value = arr[i].split('=')[1];
                //传入了key
                if (key) {
                    if (item[item1]) {
                        //进入这个里面说明有相同的参数
                        flag = true;
                        key1 = item1;
                        item[item1] += value;
                    } else {
                        item[item1] = value;
                    }
                } 
                //未传入key
                else {
                    if (item[item1]) {
                        //进入这个里面说明有相同的参数
                        flag = true;
                        key1 = item1;
                        item[item1]+=value;
                    } else {
                        item[item1] = value;
                    }
                }
            }
    //当有key,且有相同的参数,且传入的key就是相同的参数时
            if (key && flag && key == key1) {
                return item[key1].split("");
            }
    //当有key,且有相同的参数,但传入的key不是相同的参数时
            if (key && flag && key != key1) {
                return item[key]?item[key]:"";
            }
    //当没有key,且有相同的参数
            if (!key && flag) {
                item[key1] = item[key1].split("")
                return item;
            }
    //当没有key的时候
            if (!key && !flag) {
                return item?item:{};
            }
}

发表于 2021-11-19 17:54:07 回复(0)
使用正则表达式的replace方法
注意判断条件
function getUrlParam(sUrl, sKey) {
    const regex = /[\?&](\w+)=(\w+)/g;
    let params = {};
    sUrl.replace(regex, (a,k,v) => {
        if (params[k]) {
            let t = params[k];
            params[k] = [].concat(t,v);
        } else {
            params[k] = v;
        }
    });
    if (sKey) {
        return params[sKey] || "";
    } else {
        return params;
    }
}


发表于 2021-08-25 09:54:34 回复(0)
边界情况:
1.校验URL是否合法
2.考虑URL没有参数
3.没有传递key
4.key不在参数中

如果key不存在,存储起来。
如果key存在:
1.该key对应的值不是数组说明上一次存的值是第一次存的,则换成数组同时把上一次的值放进去,然后push本次的值
2.该key对应的值是数组,是则直接push
function getUrlParam(sUrl, sKey) {
  // 判断传入的url是否合法
  const isURL =
    /^(https?:\/\/)([0-9a-z.]+)(:[0-9]+)?([/0-9a-z.]+)?(\?[0-9a-z&=]+)?(#[0-9-a-z]+)?/i
  if (!isURL.test(sUrl)) return ''
  // URL没有参数的情况
  if (sUrl.indexOf('?') === -1) return ''
  // 获取参数
  let paramsString = sUrl.split('?').pop()
  let paramsArray = []
  let result = {}

  // 判断是否有哈希
  if (paramsString.indexOf('#') !== -1) {
    paramsString = paramsString.split('#').shift() // key=1&key=2&key=3&test=4
  }
  paramsArray = paramsString.split('&') // ['key=1', 'key=2', 'key=3', 'key=4']
  paramsArray.forEach((string) => {
    let [key, value] = string.split('=')
    if (result[key]) {
      if (!Array.isArray(result[key])) {
        result[key] = [result[key]]
      }
      result[key].push(value)
    } else {
      result[key] = value
    }
  }) // { key: [1,2,3,4] }
  if (sKey == undefined) return result
  return sKey in result ? result[sKey] : ''
}


发表于 2021-08-08 21:27:24 回复(0)
这个运行时间完全没有参考价值哦. :)
发表于 2021-07-28 00:39:57 回复(0)
function getUrlParam(sUrl, sKey) {
    let lp = sUrl.split('#')[0].split('?')[1].split("&")
    lp = lp.map(item => item.split("="))
    let pl = {}
    lp.forEach(item => {
        if(!pl[item[0]]){
           pl[item[0]] =item[1]
        } else {
            pl[item[0]] = [...pl[item[0]],item[1]]
        }
    })
    if(sKey === undefined){
        return pl
    }else{
        return pl[sKey] || ""
    }
}
发表于 2021-07-20 10:19:23 回复(0)
没有用正则的解题方案
function getUrlParam(sUrl, sKey) {
    var param = {
        // "key":[1,2,3],
        // "test":3
    };
    var arr = sUrl ? sUrl.split('?'):[];    //实际中为了url防止没有?#的情况
    arr = arr[1] ? arr[1].split('#'):[];
    arr = arr[0] ? arr[0].split('&'):[];
    
    arr.forEach(item=>{
        var temp = item.split('=');
        var k = temp[0], v = temp[1];
        var prev = param[k];    //前一个
      
        //是否是第一个数据
        if(!prev){ 
            param[k] = v;    // 第一个存字符串
        }else if(prev instanceof Array){
            //如果是第三个或更多的数据
            param[k].push(v);    
        }else{
            //如果是第二个数据
            param[k]=[prev, v]; 
        }
    });
    
    return  sKey ? (param[sKey] || ''): param;
}


编辑于 2021-07-15 12:57:06 回复(0)
function getUrlParam(sUrl, sKey) {
    let reg = /([^?&=]+)=([^?&=])/g
    let sKeys = sUrl.match(reg)

    let sKeyObjs = {}
    sKeys.forEach(item=>{
        let key = item.split("=")[0]
        let value = item.split("=")[1]
        if(!sKeyObjs[key]){
            sKeyObjs[key]=[]
        }
        sKeyObjs[key].push(value)
    })
    
    if(sKey === undefined){
        return sKeyObjs
    }else{
        let sKeyValues = []
        if(sKeyObjs[sKey]){
            sKeyValues = sKeyObjs[sKey]
        }
        return sKeyValues.length===0?"":sKeyValues.length>1?sKeyValues:sKeyValues[0]
    }
}

先用正则表达式来获取所有符合条件的参数
正则表达式为 
/([^?&=]+)=([^?&=])/g
然后进行数组和对象操作就行了
还要注意题目的输出要求 length === 1 是要输出单独的数据而不是长度为1的数组
发表于 2021-03-30 00:49:35 回复(0)
function getUrlParam(sUrl, sKey) {
    let urlParams = new URL(sUrl).search;
    let searchParams = new URLSearchParams(urlParams);
    
      var paramsObj = {};
      
      for(let [key, value] of searchParams.entries()){
        if(!paramsObj[key]){
          paramsObj[key] = value;
        } else {
          paramsObj[key] = [].concat(paramsObj[key],value);
        }
      }
      return !sKey ? paramsObj : paramsObj[sKey] || "";
} 哪里错了,为什么不通过呢
发表于 2021-01-29 10:54:33 回复(0)
  function getUrlParam(sUrl, sKey) {
      var start = sUrl.indexOf("?");
      if (start == -1) return null;
      var res = sUrl.substring(start + 1);
      var ressplit = res.split("&");
      var newarr = res.split("&").map(function(e) {
        var obj = {};
        var sp1 = e.split("=")[0];
        var sp2 = e.split("=")[1];
        obj[sp1] = sp2;
        return obj;
      });
      if (!sKey) return newarr;
      var newarr = newarr
        .filter(function(e) {
          return e["" + sKey + ""] != undefined;
        })
        .map(function(s) {
          return parseInt(s[sKey]) || s[sKey];
        });
      return newarr.length > 1 ? newarr : newarr.join("");
    }
case75 不知道错哪了,正则不怎么了解方法比较呆板 ,不过想知道错哪了~~~!!!
发表于 2020-05-09 17:09:35 回复(0)

问题信息

难度:
296条回答 39533浏览

热门推荐

通过挑战的用户