【问题标题】:Extracting variables from mathematical equation从数学方程中提取变量
【发布时间】:2016-07-31 06:12:34
【问题描述】:

我有一个类似

的字符串

a+(b * 6)

我正在尝试提取变量a, b, cat, dog。下面是我的代码。

        Set<String> varList = null; 
        StringBuilder sb = null; 
        String expression = "a+(b * 6) <= cat*45 && cat = dog";
        if (expression!=null)
        {
            sb = new StringBuilder(); 

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

            Pattern p = Pattern.compile("[A-Za-z\\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]);
            }
        }

        Iterator iter = varList.iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());
        }

我得到的输出是:

ab
cat
dog

需要的输出:

a
b
cat
dog

在这种情况下,变量可能会也可能不会被空格分隔。当有空白时,输出是好的。但如果变量没有用空格分隔,我得到错误的输出。有人可以建议我正确的Pattern 吗?

【问题讨论】:

标签: java regex pattern-matching


【解决方案1】:

为什么要使用正则表达式 find() 循环来提取单词,然后将它们全部连接成一个字符串来再次拆分该字符串?

只需使用正则表达式找到的单词。

当然,也就是说,在从表达式中删除空格 (\\s) 并使其匹配整个单词 (+) 之后。

Pattern p = Pattern.compile("[A-Za-z]+");
Matcher m = p.matcher(expression);
while (m.find())
{
    varList.add(m.group());
}

【讨论】:

  • 谢谢,正是我需要的:)
【解决方案2】:

如果你的变量只是一串字母,你可以简单地使用像这样的简单正则表达式来搜索它们。

正则表达式: [A-Za-z]+

Regex101 Demo

【讨论】:

  • 感谢视觉演示
【解决方案3】:

这个正则表达式应该可以工作 (variable name can start with uppercase or lowercase and can then contain digit(s), underscore, uppercase and lowercase)

\b[A-Za-z]\w*\b

Regex Demo

Java 代码

Set<String> set = new HashSet<String>();
String line = "a+(b * 6) <= cat*45 && cat = dog";
String pattern = "\\b([A-Za-z]\\w*)\\b";

Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);

while (m.find()) {
    set.add(m.group());
}
System.out.println(set);

Ideone Demo

【讨论】:

    【解决方案4】:

    我相信你应该用“[A-Za-z]+”替换你的正则表达式。 我只是用 Python 模拟的

    >>> re.findall('[A-Za-z]+', 'a+(b * 6) <= cat*45 && cat = dog')
    ['a', 'b', 'cat', 'cat', 'dog']
    >>>
    

    那么接下来,将结果列表放入一个集合中:

    >>> rs = set(re.findall('[A-Za-z]+', 'a+(b * 6) <= cat*45 && cat = dog'))
    >>> for w in rs:
    ...     print w,
    ...
    a b dog cat
    >>>
    

    【讨论】:

    • 也使用set 数据结构来查找所有唯一元素
    • @rock321987 是的,这是下一个。
    【解决方案5】:

    完整的工作代码

    public static void main(String[] args) {
        Set<String> varList = null; 
        StringBuilder sb = null; 
        String expression = "a+(b * 6) <= cat*45 && cat = dog";
        if (expression!=null)
        {
            sb = new StringBuilder(); 
    
            //list that will contain encountered words,numbers, and white space
            varList = new HashSet<String>();
    
            Pattern p = Pattern.compile("[A-Za-z\\s]+");
            Matcher m = p.matcher(expression);
    
            //while matches are found 
            while (m.find())
            {
                //add words/variables found in the expression 
                sb.append(m.group());
                sb.append(",");
            }//end while 
    
            //split the expression based on white space 
            String [] splitExpression = sb.toString().split(",");
            for (int i=0; i<splitExpression.length; i++)
            {
                if(!splitExpression[i].isEmpty() && !splitExpression[i].equals(" "))
                    varList.add(splitExpression[i].trim());
            }
        }
    
        Iterator iter = varList.iterator();
        while (iter.hasNext()) {
            System.out.println(iter.next());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      相关资源
      最近更新 更多