fe-weekly-questions
fe-weekly-questions copied to clipboard
写一个正则,根据name取cookie中的值。
function get(name){
var reg = new RegExp(name+'=([^;]*)?(;|$)');
var res = reg.exec(document.cookie);
if(!res || !res[1])return '';
try{
if(/(%[0-9A-F]{2}){2,}/.test(res)){//utf8编码
return decodeURIComponent(res);
}else{//unicode编码
return unescape(res);
}
}catch(e){
return unescape(res);
}
}
正则表达式中重点看这几句代码: '([^;])', 意思是匹配str=后面的不为; ([^;]表示非集, 也就是所有不为;的字符都能被匹配)的字符串, 该字符串出现0或更多次(), 之后将匹配到的字符串放入第一个捕获组.
const getCookie = function (name) {
let arr;
const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);
if (arr = document.cookie.match(reg)) return unescape(arr[2]);
return null;
};
接上
// "a=1; b=2; c=3"
new RegExp(`(^| )${name}=([^;]*)(;|$)`);
-
(^| )
以 '' 或 ' ' 开头 -
([^;]*)
匹配不包括;
的所有内容 -
(;|$)
匹配最后一个key-value
,因为cookie
最后一对后没有;
是不是可以简化成
function getCookie(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]*)'));
if (match) return unescape(match[2]);
}
借用楼上的,我站在新手的角度来说一下这个问题吧 😂:
function getCookie(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]*)'));
if (match) return unescape(match[2]);
}
- 获取页面上的cookie可以使用 document.cookie 这里获取到的是类似于这样的字符串:
'username=lindaidai; user-id=12345; user-roles=home, me, setting'
可以看到这么几个信息:
- 每一个cookie都是由
name=value
这样的形式存储的 - 每一项的开头可能是一个空串
''
(比如username
的开头其实就是), 也可能是一个空字符串' '
(比如user-id
的开头就是) - 每一项用
";"
来区分 - 如果某项中有多个值的时候,是用
","
来连接的(比如user-roles
的值) - 每一项的结尾可能是有
";"
的(比如username
的结尾),也可能是没有的(比如user-roles
的结尾)
- 所以我们将这里的正则拆分一下:
-
'(^| )'
表示的就是获取每一项的开头,因为我们知道如果^
不是放在[]
里的话就是表示开头匹配。所以这里(^| )
的意思其实就被拆分为(^)
表示的匹配username
这种情况,它前面什么都没有是一个空串(你可以把(^)
理解为^
它后面还有一个隐藏的''
);而|
表示的就是或者是一个" "
(为了匹配user-id
开头的这种情况) -
+name+
这没什么好说的 -
=([^;]*)
这里匹配的就是=
后面的值了,比如lindaidai
;刚刚说了^
要是放在[]
里的话就表示"除了^后面的内容都能匹配"
,也就是非的意思。所以这里([^;]*)
表示的是除了";"
这个字符串别的都匹配(*
应该都知道什么意思吧,匹配0
次或多次) - 有的大佬等号后面是这样写的
'=([^;]*)(;|$)'
,而最后为什么可以把'(;|$)'
给省略呢?因为其实最后一个cookie
项是没有';'
的,所以它可以合并到=([^;]*)
这一步。
- 最后获取到的
match
其实是一个长度为4的数组。比如:
[
"username=lindaidai;",
"",
"lindaidai",
";"
]
- 第0项:全量
- 第1项:开头
- 第2项:中间的值
- 第3项:结尾
所以我们是要拿第2项match[2]
的值
4. 为了防止获取到的值是%xxx
这样的字符序列,需要用unescape()
方法解码。