blog-md
blog-md copied to clipboard
JS 解析URL参数の正则exec()
JS 解析URL参数の正则exec()
最近被一道小题困了好久,就是关于使用正则表达式解析 url 参数问题。正好之前对 exec()方法一直搞不明白,这次借几个例子一波带走~
《JS 高程》中写了使用折腾字符串的方法来获取 url 参数,最近看网上博客一篇文章有说使用正则不但性能更佳,而且对折腾字符串方法边界条件判断过于麻烦这个问题有很好的解决,所以一起来看看正则是如何解决的吧。
代码
// 获取 search那一长串,问号开始,并不会包含锚点以及之后的内容
var search = window.location.search
// 我们用来匹配的正则表达式,分析放在后面说
var reg = /([^?&=]+)(?:=([^&?=]*)*)/g
// 返回的url 参数对象
var obj = {}
var match;
var name = ''
var value = ''
// exec()方法匹配全局时最后一次为 null
while(match = reg.exec(search)) {
name = decodeURIComponent(match[1])
value = decodeURIComponent(match[2] || '')
obj[name] = value
}
return obj
看起来比套路字符串的方法少了很多代码,不过一开始云里雾里,下面开始分析。
分析
exec() 方法
这个方法是正则表达式的方法,正好和 match()这个字符串方法是反过来的。
reg.exec(str)
str.match(reg)
当正则表达式并非全局匹配,reg.exec(str)
只会匹配一次,返回一个数组。如果 reg 没有小括号括起来,那么这个返回的数组只有一个元素,就是匹配的结果。如果 reg 中存在小括号,那么返回的数组第一个元素仍然是匹配的结果,后面的数组元素依次为每一个小括号匹配的内容。
举个李子:
var reg = /hat2/
var str = 'hat2,2hat2'
// 返回值为['hat2']
reg.exec(str)
var reg = /h(at)2/
var str = 'hat2,2hat2'
// 返回值为["hat2", "at"]
reg.exec(str)
当正则表达式开启全局匹配模式,exec()方法执行第一次就会返回第一个匹配到的数组,再次执行,会从上一次匹配到的字符串的位置开始匹配,返回第二个匹配到的数组,直至最后一次返回 null。 举个李子再:
// \d 代表数字
var reg = /hat[\d]/g
var str = 'hat2,2hat3'
// 第一次执行返回值为['hat2']
reg.exec(str)
// 第二次执行返回值为['hat3']
reg.exec(str)
// 再次执行返回值为 null,那么再下一次再执行又会从第一次返回值开始
reg.exec(str)
知道这些基本已经搞懂了 exec()的简单用法,下面来看这道题的正则表达式。
匹配 url 参数的正则
// 参考中的写法
var reg = /([^?&=]+)(?:=([^&?=]*)*)/g
// [^?*=]代表匹配除?&=三个字符以外的所有字符
// +代表匹配一次或多次,*代表匹配任意次,?代表匹配0或1次
// ([^?&=]+)代表匹配除?&=三个字符以外的字符串,至少一个字符,并捕获
// ?:代表非捕获组,所以?:=意味着不捕获
// 我自己来看,觉得这样写更容易懂~~~
// 不写分析,可不可以看懂?
var reg = /([^?&=]+)=?([^&?=]*)/g
因为参考文章中写法觉得有点怪异,非匹配模式干脆不要括起来不就好了嘛,所以用自己的写法来测试
match = reg.exec(search)
// ["_ijt=79kgs795n2hvljr0mcn1497odf", "_ijt", "79kgs795n2hvljr0mcn1497odf"]
match = reg.exec(search)
// ["sdflklj=sdfe9", "sdflklj", "sdfe9"]
match = reg.exec(search)
// ["sldfkjl", "sldfkjl", ""]
match = reg.exec(search)
// null
许多的测试用例:undefined