通过正则查找非嵌套json字符串的值

553 阅读3分钟

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