You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript解析类LDAP字符串为嵌套对象的技术问询

自定义LDAP过滤器解析方案(支持/=、!=等操作符)

我明白你的痛点——现成的ldap-filters库不支持/=、!=这类非标准操作符,只能自己动手实现解析逻辑。下面是一套针对你的需求定制的JavaScript解析方案,完全能把给定的LDAP字符串转换成你期望的嵌套对象结构。

核心思路

LDAP过滤器本质是嵌套的组(&/|/!)和原子过滤器(键+操作符+值)的组合,我们可以用栈结构来处理嵌套层级:

  1. 遇到左括号(时,识别组操作符(&/|/!),创建新的group对象并压栈父级group
  2. 遇到右括号)时,将当前group合并到父级group的filters列表中
  3. 遇到原子过滤器时,用正则匹配提取键、自定义操作符和值,加入当前group的filters

完整代码实现

function parseLdapFilter(filterStr) {
    // 先清理字符串中的空格,避免干扰解析
    const cleanedFilter = filterStr.replace(/\s+/g, '');
    const groupStack = [];
    let currentGroup = null;
    let index = 0;

    while (index < cleanedFilter.length) {
        const char = cleanedFilter[index];

        // 处理组的开始:( &/|/!
        if (char === '(') {
            index++;
            const comp = cleanedFilter[index];
            index++;
            
            const newGroup = {
                type: 'group',
                comp: comp,
                filters: []
            };

            // 如果已有当前组,先把它压入栈,再切换到新组
            if (currentGroup) {
                groupStack.push(currentGroup);
            }
            currentGroup = newGroup;
        }
        // 处理组的结束:)
        else if (char === ')') {
            // 栈不为空时,把当前组加到父组的filters里
            if (groupStack.length > 0) {
                const parentGroup = groupStack.pop();
                parentGroup.filters.push(currentGroup);
                currentGroup = parentGroup;
            }
            index++;
        }
        // 处理原子过滤器(比如 src_ip/=10.10.10.1)
        else {
            // 正则匹配:键(字母数字下划线) + 操作符(=/=/!=/~=) + 值(直到下一个))
            const filterMatch = cleanedFilter.slice(index).match(/([a-zA-Z0-9_]+)([\/!~]?=)([^)]+)/);
            if (!filterMatch) {
                throw new Error(`解析失败:位置${index}处的格式无效 - ${cleanedFilter.slice(index)}`);
            }

            const [, key, op, value] = filterMatch;
            currentGroup.filters.push({
                type: 'filter',
                key: key,
                op: op,
                value: value
            });

            // 把指针移动到匹配内容的末尾
            index += filterMatch[0].length;
        }
    }

    return currentGroup;
}

// 测试你的LDAP过滤器字符串
const targetFilter = '(&(&(|(src_ip/=10.10.10.1)(dst_ip/=10.10.10.1))(|(src_ip/=10.10.11.1)(dst_ip/=10.10.11.1)))(raw=*))';
const parsedResult = parseLdapFilter(targetFilter);

// 打印格式化后的结果
console.log(JSON.stringify(parsedResult, null, 2));

解析结果验证

运行代码后,你会得到完全符合预期的嵌套结构:

{
  "type": "group",
  "comp": "&",
  "filters": [
    {
      "type": "group",
      "comp": "&",
      "filters": [
        {
          "type": "group",
          "comp": "|",
          "filters": [
            {
              "type": "filter",
              "key": "src_ip",
              "op": "/=",
              "value": "10.10.10.1"
            },
            {
              "type": "filter",
              "key": "dst_ip",
              "op": "/=",
              "value": "10.10.10.1"
            }
          ]
        },
        {
          "type": "group",
          "comp": "|",
          "filters": [
            {
              "type": "filter",
              "key": "src_ip",
              "op": "/=",
              "value": "10.10.11.1"
            },
            {
              "type": "filter",
              "key": "dst_ip",
              "op": "/=",
              "value": "10.10.11.1"
            }
          ]
        }
      ]
    },
    {
      "type": "filter",
      "key": "raw",
      "op": "=",
      "value": "*"
    }
  ]
}

扩展优化建议

如果需要处理更复杂的场景,可以做以下优化:

  • 支持值中的转义字符(比如\(、\)),需要修改正则来处理转义逻辑
  • 增加对!(非操作)组的特殊处理逻辑
  • 添加错误捕获和友好的错误提示

内容的提问来源于stack exchange,提问作者Mon Koth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:33:59