package net.greghaines.arithmeticparser.regexor;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.greghaines.arithmeticparser.ArithmeticParser;

public class RegexArithmeticParser implements ArithmeticParser {
    
    private static final Pattern parenPattern = Pattern.compile("\\(([^\\)\\(]+)\\)");
    private static final Pattern multiDividePattern = Pattern.compile("([0-9]+(\\.[0-9]+)?)\\s*([\\*\\/])\\s*([0-9]+(\\.[0-9]+)?)");
    private static final Pattern addSubPattern = Pattern.compile("([0-9]+(\\.[0-9]+)?)\\s*([\\+\\-])\\s*([0-9]+(\\.[0-9]+)?)");
    private static final Pattern[] opPatterns = { multiDividePattern, addSubPattern };

    /**
     * {@inheritDoc}
     */
    @Override
    public double evaluate(final String expression) {
        String text = expression;
        final Matcher p = parenPattern.matcher(text);
        while (p.reset(text).find()) {
            text = text.substring(0, p.start()) + evaluate(p.group(1)) + text.substring(p.end());
        }
        for (final Pattern opPattern : opPatterns) {
            p.usePattern(opPattern);
            while (p.reset(text).find()) {
                text = text.substring(0, p.start())
                        + (p.group(3).equals("*") ? (evaluate(p.group(1)) * evaluate(p.group(4))) : (p.group(3).equals("/") ? (evaluate(p.group(4)) == 0 ? Double.NaN
                                : (evaluate(p.group(1)) / evaluate(p.group(4)))) : (p.group(3).equals("+") ? (evaluate(p.group(1)) + evaluate(p.group(4))) : (evaluate(p.group(1)) - evaluate(p
                                .group(4)))))) + text.substring(p.end());
            }
        }
        return Double.parseDouble(text);
    }
}

@@ -398,38 +398,44 @@
 tern.compile(%22(%5B
+-%5D?%5B
 0-9%5D+(
+?:
 %5C%5C.%5B0-9%5D+)?)%5C%5Cs*
@@ -442,38 +442,44 @@
 (%5B%5C%5C*%5C%5C/%5D)%5C%5Cs*(%5B
+-%5D?%5B
 0-9%5D+(
+?:
 %5C%5C.%5B0-9%5D+)?)%22);%0D
@@ -547,22 +547,28 @@
 pile(%22(%5B
+-%5D?%5B
 0-9%5D+(
+?:
 %5C%5C.%5B0-9%5D
@@ -591,22 +591,28 @@
 %5D)%5C%5Cs*(%5B
+-%5D?%5B
 0-9%5D+(
+?:
 %5C%5C.%5B0-9%5D
@@ -816,24 +816,82 @@
 ression) %7B%0D%0A
+//        System.out.println(%22evaluate: %22 + expression);%0D%0A
         Stri
@@ -1246,32 +1246,34 @@
 ext).find()) %7B%0D%0A
+//
                 
@@ -1276,210 +1276,570 @@
     
-text = text.substring(0, p.start())%0D%0A                        + (p.group(3).equals(%22*%22) ? (evaluate(p.group(1)) * evaluate(p.group(4))) : (p.group(3).equals(%22/%22) ? (evaluate(p.group(4)) == 0 ? Double.NaN
+System.out.println(%22PRE text: %22 + text);%0D%0A                final String arg1 = p.group(1);%0D%0A                final String operator = p.group(2);%0D%0A                final String arg2 = p.group(3);%0D%0A//                System.out.println(%22arg1: %22 + arg1);%0D%0A//                System.out.println(%22operator: %22 + operator);%0D%0A//                System.out.println(%22arg2: %22 + arg2);%0D%0A                final double result;%0D%0A                switch (operator) %7B%0D%0A                case %22*%22: %7B%0D%0A                    result = evaluate(arg1) * evaluate(arg2);%0D%0A                    break;
 %0D%0A  
@@ -1844,32 +1844,35 @@
                 
+%7D%0D%0A
                 
@@ -1875,167 +1875,388 @@
     
-: (evaluate(p.group(1)) / evaluate(p.group(4)))) : (p.group(3).equals(%22+%22) ? (evaluate(p.group(1)) + evaluate(p.group(4))) : (evaluate(p.group(1)) - evaluate(p
+case %22/%22: %7B%0D%0A                    result = evaluate(arg1) / evaluate(arg2);%0D%0A                    break;%0D%0A                %7D%0D%0A                case %22+%22: %7B%0D%0A                    result = evaluate(arg1) + evaluate(arg2);%0D%0A                    break;%0D%0A                %7D%0D%0A                case %22-%22: %7B%0D%0A                    result = evaluate(arg1) - evaluate(arg2);%0D%0A                    break;
 %0D%0A  
@@ -2261,32 +2261,35 @@
                 
+%7D%0D%0A
                 
@@ -2292,47 +2292,354 @@
     
-.group(4)))))) + text.substring(p.end()
+default: %7B%0D%0A                    throw new IllegalArgumentException(%22Unknown operator: %22 + operator);%0D%0A                %7D%0D%0A                %7D%0D%0A//                System.out.println(%22result: %22 + result);%0D%0A                text = text.substring(0, p.start()) + result + text.substring(p.end());%0D%0A//                System.out.println(%22POST text: %22 + text
 );%0D%0A

Handle negative numbers correctly in regex version