Requirements were to create a constructor for a complex number, that receives a string. For example: \$3+5i\$. The regex extracts positive or negative numbers from the string with optional decimal.My professor told me that my regex was beyond wrong:public Complex(String str) {        ArrayList<Double> list = new             ArrayList<Double>();        Pattern p = Pattern.compile([-+]?[0-9]*\\.?[0-9]);        // toString() handles the letter i        // find positive and negative doubles in string and add to list        Matcher m = p.matcher(str);        while (m.find()) {            double num = Double.parseDouble(m.group());            list.add(num);        }        this.re = list.get(0);        this.im = list.get(1);}Here is a link to the class if you need a better understanding of the code.He then posted his chosen correct solution, which I found to be repetitive. He may argue that I am not checking for i, but I see no point of storing i if we are not using it later.In addition, if he argues that I am not checking for and storing i, that would mean that if I did store them, I would explicitly have to go exclude the i from the string when I perform mathematical operations on the numbers. It seems counter-productive.Here is the solution he preferred:public Complex(String c) {      String numberNoWhiteSpace = c.replaceAll(\\s,);      // Matches complex number with BOTH real AND imaginary parts.        // Ex: -3-2.0i      Pattern patternA = Pattern.compile(([-]?[0-9]+\\.?[0-9]?)([-|+]+[0-9]+\\.?[0-9]?)[i$]+);      // Matches ONLY real number.      // Ex: 3.145      Pattern patternB = Pattern.compile(([-]?[0-9]+\\.?[0-9]?)$);      // Matches ONLY imaginary number.      // Ex: -10i      Pattern patternC = Pattern.compile(([-]?[0-9]+\\.?[0-9]?)[i$]);      Matcher matcherA = patternA.matcher(numberNoWhiteSpace);      Matcher matcherB = patternB.matcher(numberNoWhiteSpace);      Matcher matcherC = patternC.matcher(numberNoWhiteSpace);      if (matcherA.find()) {          real = Double.parseDouble(matcherA.group(1));          imaginary = Double.parseDouble(matcherA.group(2));      } else if (matcherB.find()) {          real = Double.parseDouble(matcherB.group(1));          imaginary = 0;      } else if (matcherC.find()) {          real = 0;          imaginary = Double.parseDouble(matcherC.group(1));      }   }
Parsing a complex number using regular expressions
java;parsing;regex;comparative review;constructor
Both of your solutions are wrong, in different ways.  Yours is worse, though, because it fails in a way that can actually succeed in giving completely wrong answers.Your solutionYour technique is, as your professor noted, sloppy.  It falls apart in several cases that I would consider reasonable inputs:Pure imaginary numbers such as 5iNo imaginary component, such as 1No imaginary coefficient, such as 5+iImaginary number with a space, such as 3 - 3iDecimals more precise than one-tenth, such as 3.14Furthermore, using an ArrayList seems extravagant.  You shouldn't need one.Professor's solution1Sanitizing the input by discarding spaces  is that a good idea?  Why?  Is there another way to handle spaces?Why three Patterns, three Matchers, and three .find()s?  Can it be done with fewer?Within each pattern, is your regex more correct, or his?  Can you spot any bugs in his character classes (i.e. the stuff inside [square brackets])?Are there any inputs that also fail with his code?  Does his code accept any inputs that should be considered invalid?1 We shouldn't really be criticizing code that you didn't write, so I'll give you some questions to ponder instead.