1. 目标
用js写一个正则表达式函数,它接收两个参数,一个字符串key和一个待提取的长字符串,第一个参数是一个json中的key,需要去第二个参数中去找这个key对应的值,第二个参数类似一个json字符串,该函数输出该key对应的value,如果没有返回null。
2. json字符串(解析的token字符串)
这个字符串中包含两个json字符串,尾部还有一些干扰信息
'{"alg":"HS256"}{"uid":"6f147de2-8672-4148-a8fa-5388e6e0765e","sub":"02327;1685502968784","user_name":"02327","iss":"EIS_ADMIN_XS_TMKJ","exp":1685589368,"iat":1685502968,"jti":"6f147de2-8672-4148-a8fa-5388e6e0765e"}\x06틐㴆\x0F9抰㡏㬐TF D鋝ȇ`\x1Aᙻ\x10\x00\x00'
3. 函数编写
function extractValueByKey(key, longString) {
const regex = new RegExp(`{[^{}]*"${key}"\\s*:\\s*("[^"]*"|\\d+|true|false|null)[^{}]*}`, 'g');
let result = null;
let match;
while ((match = regex.exec(longString)) !== null) {
try {
const jsonMatch = JSON.parse(match[0]);
if (jsonMatch.hasOwnProperty(key)) {
result = jsonMatch[key];
break;
}
} catch (error) {
// Ignore parsing errors
}
}
return result;
}
4. 正则含义说明
{[^{}]*"${key}"\\s*:\\s*("[^"]*"|\\d+|true|false|null)[^{}]*}
4.1. {:匹配左大括号 {,表示 JSON 对象的开始。
4.2. [^{}]*:匹配任意数量的非大括号字符(不包括 { 和 })。这部分用于匹配 JSON 对象内部的内容,但不包括嵌套的 JSON 对象。
4.3. ":匹配双引号 ",表示 key 的开始。
4.4. ${key}:插入变量 key,表示要查找的 key。
4.5. ":匹配双引号 ",表示 key 的结束。
4.6. \\s*:匹配任意数量的空白字符(包括空格、制表符、换行符等)。
4.7. ::匹配冒号 :,表示 key 和 value 之间的分隔符。
4.8. \\s*:匹配任意数量的空白字符(包括空格、制表符、换行符等)。
4.9. ("[^"]*"|\\d+|true|false|null):这部分匹配 value,分为以下几种情况:
"[^"]*":匹配双引号包围的字符串。[^"]表示非双引号字符,*表示匹配任意数量。\\d+:匹配一个或多个数字字符。true:匹配布尔值true。false:匹配布尔值false。null:匹配空值null。
这些情况之间用竖线 | 分隔,表示匹配其中任意一种情况。
4.10. [^{}]*:匹配任意数量的非大括号字符(不包括 { 和 })。这部分用于匹配 JSON 对象内部的内容,但不包括嵌套的 JSON 对象。
4.11. }:匹配右大括号 },表示 JSON 对象的结束。
整个正则表达式的作用是在给定的长字符串中查找包含指定 key 的 JSON 对象,并尽可能匹配最小的 JSON 对象范围。
5. 测试
var longString = '{"alg":"HS256"}{"uid":"6f147de2-8672-4148-a8fa-5388e6e0765e","sub":"02327;1685502968784","user_name":"02327","iss":"EIS_ADMIN_XS_TMKJ","exp":1685589368,"iat":1685502968,"jti":"6f147de2-8672-4148-a8fa-5388e6e0765e"}\x06틐㴆\x0F9抰㡏㬐TF D鋝ȇ`\x1Aᙻ\x10\x00\x00';
extractValueByKey("user_name", longString); // 02327
extractValueByKey("sub", longString); // 02327;1685502968784