正则表达式模式匹配&从数学/代数表达式中提取变量

时间:2012-06-28 20:08:02

标签: java regex pattern-matching

我正在尝试编写一个正则表达式/方法,用于从表示“数学/代数表达式”的输入字符串中提取变量,以及一个看起来像“PROPERTY(AnyOtherAplhaNumeric)”的特殊模式,它也可以是变量。< / p>

我对变量的定义:

1)只能包含字母数字值

2)必须至少为1个字符或更多

3)不能以数字开头,必须以[A-Za-z]

开头

4)变量例如“X”,可以用这个字符串“PROPERTY(X)”包围,因此变量变为“PROPERTY(X)”

我目前的方法&amp;正则表达式(仅在某些情况下有效):

public Set<String> extractUniqueVarsFromExpression(String expression) {
        Set<String> varsSet = null;
        Pattern p = null;
        Matcher m = null;
        System.out.println(expression);
        if (expression != null) {
            varsSet = new java.util.LinkedHashSet<String>();
            //"[A-Za-zPROPERTY(?)_][A-Za-z0-9PROPERTY(?)_]*||[A-Za-z_][A-Za-z0-9_]*"
            //"[[A-Za-z_][A-Za-z0-9_]*"
            p = Pattern.compile("[A-Za-zPROPERTY(?)_][A-Za-z0-9PROPERTY(?)_]*||[A-Za-z_][A-Za-z0-9_]*",
                    Pattern.CASE_INSENSITIVE);
            m = p.matcher(expression);
            while (m.find()) {

                    String group = m.group().trim();
                //do not add duplicates     

                         if (!varsSet.contains(group)) 
                         {
                    varsSet.add(group);

                    System.out.println(" Variable : " + group);
                         }//end if not duplicate 

            }// end while

        }
        System.out.println();
        return varsSet;
    }

实例/个案:

Ex#1:

输入:[(ibdweight / ibdheight)* ibdheight] * 703

输出:

变量:PROPERTY(ibdweight)

变量:PROPERTY(ibdheight)

前2:

输入:[ibdweight / ibdheight * ibdheight] * 703

输出:

变量:ibdweight

变量:ibdheight

Ex#3:

输入:[物业(ibdweight)/ [物业(ibdheight)*物业(ibdheight)] * 703

输出:

变量:PROPERTY(ibdweight)

变量:PROPERTY(ibdheight)

前#:4

这些情况不起作用(示例4到6):

问题是括号被选为变量:

输入:(质量*(加速+等))

输出:

变量:(

变量:质量

变量:加速

变量:无论

变量:))

前#:5

问题是括号被选为变量:

输入:(基础*高度)/ 2

输出:

变量:(

变量:基础

变量:高度

变量:)

前#:6

问题是括号被选为变量或附加到变量:

输入:[(((var * var2)var3)+(var1 / var4)var5)/ var6]

输出:

变量:((

变量:var

变量:var2

变量:)

变量:var3

变量:(

变量:var1

变量:var4

变量:var5)

变量:var6

2 个答案:

答案 0 :(得分:4)

正则表达式的问题在于括号中有两个括号和字样。括号用于指定一组字符,而不是字符串,其中任何成员都匹配。

适用于您的简单(尽管可能不是最佳)变体是:
(PROPERTY\([A-Za-z][A-Za-z0-9_]*\))|([A-Za-z][A-Za-z0-9_]*)

稍微好一点的版本是:
(PROPERTY\([A-Za-z]\w*\))|([A-Za-z]\w*)

答案 1 :(得分:0)

部分问题在于您正在考虑正则表达式的方式。

举个例子:

    [A-Za-zPROPERTY(?)_]

这实际上是一个“角色类”,它的行为与你期望的不同。它将匹配输入字符串中与类中任何字符匹配的任何单个字符。它不会将PROPERTY视为单个实体,而是将其作为单独的大写字母(无论如何已经包含在AZ中)。此外,在您的角色类中有(?)匹配“(”,我相信它不是什么你想要的。