如何从条件字符串中提取键值映射关系?
问题:将SQL条件字符串转换为键值映射数组
原始条件字符串:
const string = "DEVICE_SIZE IN ('036','048','060','070') AND DEVICE_VOLTAGE IN ('1','3') AND NOT DEVICE_DISCHARGE_AIR IN ('S') AND NOT DEVICE_REFRIGERANT_CIRCUIT IN ('H','C')";
需求:将上述字符串转换为键值映射数组,每个元素是包含属性名和对应值数组的对象,预期结果如下:
[ { "DEVICE_SIZE": ["036", "048", "060", "070"] }, { "DEVICE_VOLTAGE": ["1", "3"] }, { "NOT DEVICE_DISCHARGE_AIR": ["S"] }, { "NOT DEVICE_REFRIGERANT_CIRCUIT": ["H", "C"] }, ];
之前尝试的代码(无法得到预期结果):
const string = "DEVICE_SIZE IN ('036','048','060','070') AND DEVICE_VOLTAGE IN ('1','3') AND NOT DEVICE_DISCHARGE_AIR IN ('S') AND NOT DEVICE_REFRIGERANT_CIRCUIT IN ('H','C')"; const res = string.split('IN '); const regExp = /\(([^)]+)\)/; const Y = 'AND'; const data = res.map((item) => { if (regExp.exec(item)) { return { [item.slice(item.indexOf(Y) + Y.length)]: regExp.exec(item)[1], }; } }); console.log('data ', data);
解决方案
可以通过正则表达式匹配每个条件块,再拆分属性名和值数组,具体代码如下:
const string = "DEVICE_SIZE IN ('036','048','060','070') AND DEVICE_VOLTAGE IN ('1','3') AND NOT DEVICE_DISCHARGE_AIR IN ('S') AND NOT DEVICE_REFRIGERANT_CIRCUIT IN ('H','C')"; // 匹配每个条件块:(NOT )?[A-Z_]+ IN \(([^)]+)\) const conditionRegex = /(NOT\s+)?([A-Z_]+)\s+IN\s+\(([^)]+)\)/g; const result = []; let match; while ((match = conditionRegex.exec(string)) !== null) { // 拼接属性名(包含NOT前缀) const key = match[1] ? `${match[1].trim()} ${match[2]}` : match[2]; // 处理值数组:拆分、去引号、去空格 const values = match[3].split(',') .map(val => val.trim().replace(/'/g, '')); result.push({ [key]: values }); } console.log(result);
代码说明:
- 正则匹配:使用
/(NOT\s+)?([A-Z_]+)\s+IN\s+\(([^)]+)\)/g全局匹配每个条件块,捕获三个分组:- 第一个分组:可选的
NOT前缀 - 第二个分组:属性名称(如DEVICE_SIZE)
- 第三个分组:括号内的所有值字符串
- 第一个分组:可选的
- 属性名处理:如果有NOT前缀,就将前缀和属性名拼接,否则直接用属性名
- 值数组处理:将括号内的字符串按逗号拆分,逐个去除前后空格和单引号,得到干净的值数组
- 组装结果:将每个键值对包装成对象,推入结果数组
运行上述代码后,即可得到符合预期的键值映射数组。
内容的提问来源于stack exchange,提问作者Hello World
相关产品推荐
相关产品推荐

