想要一个用于解析字符串公式的java库

时间:2013-08-22 17:54:42

标签: java parsing variables expression formula

这是我在这里的第一篇文章。很抱歉,如果我这么做错了。

我的任务是从字符串公式获取变量列表,如“A + B *(C - 21.2)/ DD”。 我在Apache Jexl lib中找到了解决方案。这项工作正是我所需要的。

JexlEngine engine = new JexlEngine();
Set<List<String>> exactlyWhatINeed = engine.createScript("A+B+C/D").getVariables()

这为我提供了解析变量列表,完美。

但我有一个大麻烦。我的变量可以用俄语写成。 所以公式可以像“23 - О+ПАНЬКИ* simpleANSI_Var”。该库抛出异常,coz变量名称必须在ANSI和32之间。

我需要类似的东西,为googlesearch和测试花了两天时间。我很累,如果有人知道解决方案,请帮助我。我只需要一个var的列表,我知道如何执行此操作并通过脚本引擎或其他库如JEval获取结果。

先谢谢你,朋友们。 是的。对不起,我的英语很糟糕。

1 个答案:

答案 0 :(得分:0)

扩展我的评论,这是我想象的那种解决方案:

class HaxlEngine
{
    static boolean isANSI(final char c)
    {
        return c <= 0x7F;
    }

    public static Set<List<String>> doSum(String formula)
    {
        JexlEngine engine = new JexlEngine();
        final Map<Character, Character> mappedChars = new HashMap<>();
        char ansiCounter = 'A';
        for(final char c : formula.toCharArray())
        {
            if(!isANSI(c))
            {
                char newValue;
                do
                {
                    newValue = ansiCounter++;
                }
                while(formula.contains(String.valueOf(newValue)));
                mappedChars.put(c, newValue);
                formula = formula.replace(c, newValue);
            }
        }
        final Set<List<String>> exactlyWhatINeed = engine.createScript(formula).getVariables();
        for(final List<String> list : exactlyWhatINeed)
        {
            for(String str : list)
            {
                for(final Map.Entry<Character, Character> entry : mappedChars.entrySet())
                {
                    str = str.replace(entry.getValue(), entry.getKey());
                }
            }
        }
        return exactlyWhatINeed;
    }                                                       
}

这会检查您提供给它的公式中的每个字符,并用标准ABC等替换任何无效ANSI字符的字符。我不能不测试实际的引擎部件,但是替换件似乎在我的测试中起作用(见下文),所以我相信当你插入库时它会起作用。

static boolean isANSI(final char c)
{
    return c <= 0x7F;
}


static String testReplaceNonANSI(String maybeANSI)
{
    final Map<Character, Character> mappedChars = new HashMap<>();
    char ansiCounter = 'A';
    for(final char c : maybeANSI.toCharArray())
    {
        if(!isANSI(c))
        {
            char newValue;
            do
            {
                newValue = ansiCounter++;
            }
            while(maybeANSI.contains(String.valueOf(newValue)));
            mappedChars.put(c, newValue);
            maybeANSI = maybeANSI.replace(c, newValue);
        }
    }
    return maybeANSI;
}

public static void main(String[] args)
{
    String a = "(A+B/C) * X";
    String b = "(О+А/C) * П";
    System.out.println(testReplaceNonANSI(a)); //(A+B/C) * X
    System.out.println(testReplaceNonANSI(b)); //(A+B/C) * C
}