Java正则表达式,匹配数学表达式中的变量

Java正则表达式,匹配数学表达式中的变量,java,regex,pattern-matching,Java,Regex,Pattern Matching,我有一个字符串输入,表示如下公式: BMI = ( Weight / ( Height * Height ) ) * 703 我希望能够将所有合法变量提取到字符串[] 法律变量的确定规则与Java变量命名约定几乎相同,只允许使用字母数字字符: 任何字母大写或小写,后面都可以跟一个数字 任何单词/文本 后跟数字的任何单词/文本 因此,我希望输出如下所示: BMI Weight Height 这是我当前的尝试: /* helper method , find all variables i

我有一个字符串输入,表示如下公式:

BMI = ( Weight / ( Height  * Height ) ) * 703
我希望能够将所有合法变量提取到
字符串[]

法律变量的确定规则与Java变量命名约定几乎相同,只允许使用字母数字字符:

  • 任何字母大写或小写,后面都可以跟一个数字
  • 任何单词/文本
  • 后跟数字的任何单词/文本
因此,我希望输出如下所示:

BMI
Weight
Height
这是我当前的尝试:

/* helper method , find all variables in expression,
 * Variables are defined a alphabetical characters a to z, or any word , variables cannot have numbers at the beginning
 * using regex pattern "[A-Za-z0-9\\s]"
 */
public static List<String> variablesArray (String expression)
{
    List<String> varList = null; 
    StringBuilder sb = null; 
    if (expression!=null)
    {
        sb = new StringBuilder(); 

        //list that will contain encountered words,numbers, and white space
        varList = new ArrayList<String>();

        Pattern p = Pattern.compile("[A-Za-z0-9\\s]");
        Matcher m = p.matcher(expression);

        //while matches are found 
        while (m.find())
        {
            //add words/variables found in the expression 
            sb.append(m.group());
        }//end while 

        //split the expression based on white space 
        String [] splitExpression = sb.toString().split("\\s");
        for (int i=0; i<splitExpression.length; i++)
        {
            varList.add(splitExpression[i]);
        }
    }
    return varList; 
}
使用:

所以你需要做的只是,这是一个简单的任务



请参阅并测试代码。

此简单正则表达式应与所有变量匹配:

"[A-Za-z_][A-Za-z0-9_]*"
我冒昧地在名称中包含了
,但如果您确实不想:

"[A-Za-z][A-Za-z0-9]*"

不可能唯一地匹配变量,但您可以将匹配项插入到
集合中以删除重复项。

我不确定为什么要创建字符串并将其拆分为数组。除了效率低下之外,除非每个ID出现后都跟有空格,否则该方法将无法工作

这里有一个更简单的代码,允许在输出中重复。要消除重复,只需将
List
ArrayList
替换为
Set
HashSet

public class Test {

    public static List<String> variablesArray(String expression) {
        if (expression != null) {
            ArrayList<String> vars = new ArrayList<String>();
            Pattern p = Pattern.compile("[a-z][a-z0-9]*", Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher(expression);
            while (m.find()) {
                vars.add(m.group());
            }
            return vars;
        }
        return null;
    }

    public static void main(String[] args) {
        List<String> vars = variablesArray("BMI=(Weight/(Height*Height)) * 70");
        for (String var : vars) {
            System.out.println(var);
        }
    }
}

最后,我想知道你想要实现什么。在表达式中包含标识符列表似乎不是很有用。例如,如果您试图对表达式求值,则此ID列表将不是您所需要的。

好的,您的问题是什么?我想要一个正则表达式,它在给定的字符串中表示数学公式,提取所有变量。为什么是正则表达式?你在工作中使用了错误的工具。对于一个数学表达式,你应该看看扫描器/解析器的组合。我没有使用错误的工具,你不知道我的项目的全部范围,如果你阅读上面粗体的标准,问题是非常清楚的!!!当我将正则表达式放在模式p=Pattern.compile(“(?:^ |)(?在StackOverFlow中查看它,Thanks@AryanNaim-答案用Java代码更新您不需要所有这些反斜杠。字符类中的所有字符都会失去其特殊含义,除了首字母
^
和连字符(当连字符不是第一个或最后一个时)@Bohemian-谢谢你的教训,我已经更新了代码,但是正如你所看到的,其中一个(
\\-
)仍然需要转义,这很有意义:)谢谢你,正则表达式起作用了,谢谢你花时间阅读我的问题,而不是像用户一样否决它EJB@AryanNaim:我建议您不要在评论中抨击其他用户。请将其编辑掉。为了便于学习,我将指出这些表达式与单个字母的变量名不匹配。@Gene:我为什么选择是这样吗?谢谢你的评论。谢谢你正则表达式工作了,谢谢你花时间阅读我的问题,而不是像用户EJB一样否决它
"[A-Za-z_][A-Za-z0-9_]*"
"[A-Za-z][A-Za-z0-9]*"
public class Test {

    public static List<String> variablesArray(String expression) {
        if (expression != null) {
            ArrayList<String> vars = new ArrayList<String>();
            Pattern p = Pattern.compile("[a-z][a-z0-9]*", Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher(expression);
            while (m.find()) {
                vars.add(m.group());
            }
            return vars;
        }
        return null;
    }

    public static void main(String[] args) {
        List<String> vars = variablesArray("BMI=(Weight/(Height*Height)) * 70");
        for (String var : vars) {
            System.out.println(var);
        }
    }
}
return vars.toArray(new String [vars.size()]);