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

如何让Apache Commons JEXL表达式匹配正则表达式数组?

自定义Apache Commons JEXL =~ 运算符实现正则数组匹配

Apache Commons JEXL 提供的=~(In or Match)运算符默认有两种行为:

  • 当右侧为字符串时,作为正则匹配器工作:
    "abcdef" =~ "abc.*"
    
  • 当右侧为字符串数组时,作为包含运算符工作(判断左侧字符串是否在数组中):
    "a" =~ ["a","b","c","d","e","f"]
    

但默认不支持右侧数组元素作为正则表达式匹配的场景,比如"abcdef" =~ ["abc.*", "a.d.*"]预期返回true,但默认逻辑会判断字面量是否相等,因此返回false。以下是实现该特性的方法:


一、通过Java代码修改JexlEngine

核心思路是自定义JexlOperatorStrategy,重写=~运算符的处理逻辑,当右侧为数组/集合时,遍历其中的字符串作为正则表达式匹配左侧内容。

1. 自定义运算符策略类

import org.apache.commons.jexl3.*;
import java.util.Collection;
import java.util.regex.Pattern;

public class RegexArrayOperatorStrategy extends JexlOperatorStrategy {
    private final JexlOperatorStrategy delegate;

    public RegexArrayOperatorStrategy(JexlOperatorStrategy delegate) {
        this.delegate = delegate;
    }

    @Override
    public Object evaluate(JexlOperator op, Object lhs, Object rhs) {
        // 仅处理=~(MATCH)运算符
        if (op == JexlOperator.MATCH) {
            // 左侧必须是字符串类型
            if (lhs instanceof String strLhs) {
                // 处理数组类型的右侧
                if (rhs instanceof Object[] arrRhs) {
                    for (Object obj : arrRhs) {
                        if (obj instanceof String regex) {
                            if (Pattern.matches(regex, strLhs)) {
                                return true;
                            }
                        }
                    }
                    return false;
                }
                // 处理集合类型的右侧(比如List)
                else if (rhs instanceof Collection<?> colRhs) {
                    for (Object obj : colRhs) {
                        if (obj instanceof String regex) {
                            if (Pattern.matches(regex, strLhs)) {
                                return true;
                            }
                        }
                    }
                    return false;
                }
            }
        }
        // 其他情况沿用默认运算符逻辑
        return delegate.evaluate(op, lhs, rhs);
    }
}

2. 配置并使用自定义引擎

// 创建带有自定义运算符策略的JexlEngine
JexlEngine jexl = new JexlBuilder()
        .operatorStrategy(new RegexArrayOperatorStrategy(JexlEngine.DEFAULT_STRATEGY))
        .create();

// 测试正则数组匹配表达式
JexlExpression expr = jexl.createExpression("\"abcdef\" =~ [\"abc.*\", \"a.d.*\"]");
Object result = expr.evaluate(null);
System.out.println(result); // 输出true

二、在JEXL表达式中的使用

配置好自定义引擎后,表达式写法无需额外修改,直接使用数组语法即可:

# 匹配数组中任意一个正则表达式
"abcdef" =~ ["abc.*", "a.d.*"]

# 支持带正则标志的写法(比如忽略大小写)
"ABCDEF" =~ ["(?i)abc.*", "a.d.*"]

若数组中包含非字符串元素,自定义策略会跳过该元素,继续匹配其他正则表达式;若所有元素都不匹配,则返回false。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:01:07