2

i want to extract an equation constants(i.e integer or double NOT followed by a letter like say "x") from a string. e.g eqn = "30.14x^2 + 55.69x + 60.1 = 100". So far, i can get the coefficients of x using

([\\+\\-])?(\\d+(\\.\\d+)?)x

which gives 55.69x or 30.14x in this case.

Now i want to get the constants and I've tried regex below to extract +60.1 or 100

(?<!^)([\\+\\-])?(\\d+(\\.\\d+)?)(?!x)

However this doesn't work.Any help would be highly appreciated since I've on this for a month or so.

2
  • I would split the string (first using "=" as a delimiter, then using "+" as a delimiter), the result should be easier to work with. Commented Jun 22, 2012 at 12:48
  • Yes veger, spliting the expression using "=" so i what i've been doing. just didn't want to get into the details. so now am concentraing on one side of the expression that is 30.14x^2 + 55.69x + 60.1 only Commented Jun 23, 2012 at 10:09

4 Answers 4

1

what about

 (?<!\^)(-|\+)?[\d.]++(?!x)

?

this variant uses the possessive quantifier ( the "++"), may be less strict with invalid numbers, but if the strings are syntactically correct, this does not matter.

Sign up to request clarification or add additional context in comments.

2 Comments

(?<!\\^)(-|\\+)?[\\d.]++(?!x) works thanks alot and gives 60.1 i don't understand the construct [\\d.]++ in the regex and i would appreciate if you explained alot more or provided a link to more information. thanks alot again.
with ++ the expression before will not backtrack to find different solutions. It is not only greedy, but will not give up on characters already matched. Thus it does not match parts of the coefficients that are also digit/dot sequences not before a 'x'. See http://www.regular-expressions.info/possessive.html. A regex implementation may also benefit from possessive quantifiers when regarding performance.
0

Here's a way to extract those values in a couple of passes:

public static void main(String[] args) {

    String eqn = "30.14x^2 + 55.69x + 60.1 = 100";

    String numberRegex = "[\\d]+(?:[\\.]{1}[\\d]+)?";
    String symbolsRegex = "=+-/\\\\*\\^";

    String coefRegex = "("+numberRegex+")([a-z]{1})";
    Pattern p = Pattern.compile(coefRegex);
    Matcher m = p.matcher(eqn);
    while (m.find()) {
        System.out.println("coefficient: " + m.group(1) + " -- " + m.group(2));
    }

    String constRegexp = "([^ " + symbolsRegex + "]" + numberRegex + "(?:[ ]{1}|$))";
    p = Pattern.compile(constRegexp);
    m = p.matcher(eqn);
    while (m.find()) {
        System.out.println("constant: " + m.group(1));
    }

}

Output:

coefficient: 30.14 -- x
coefficient: 55.69 -- x
constant: 60.1 
constant: 100

Just to add the literal values of the regex I used above:

String coefRegex = "([\\d]+(?:[\\.]{1}[\\d]+)?)([a-z]{1})";
String constRegexp = "([^ =+-/\\\\*\\^][\\d]+(?:[\\.]{1}[\\d]+)?(?:[ ]{1}|$))";

1 Comment

Thanks sudocode, both String constRegexp and String coefRegex work for their respective duties.
0

This should work:

([\\+\\-])?(\\d+(\\.\\d+)?)(?![\\d.x])

[\\d.x] works because it eliminates partial numbers. E.g.: For 30.14x, 30.14 wouldn't match (?!x) but 30.1 would.

1 Comment

Thanks tibfot. ([\\+\\-])?(\\d+(\\.\\d+)?)(?![\\d.x]) works fine and i just have to add the group (?<!\\^) to eliminate the 2. However, just like Sahand Mozaffari solution about, i would appreciate an explaination to why the group (?![\\d.x]) works and the group i have used (?!x) doesn't work!. My reasoning was that since am matching double or integer NOT followed by an "x", then the negative lookahead (?!x) would work, but i didn't. Instead (?![\\d.x]) works! Thanks again
0

What is wrong with your regex is that you did not escape ^, thus it means beginning of the string. And you also had not accounted for the substrings preceded by a digit or a decimal-point. Neither for the ones proceeded by one. Hence the correct form of your regex would be:

(?<!(\\^|\\d|\\.))[+-]?(\\d+(\\.\\d+)?)(?!(x|\\d|\\.))

which works ok. And also if you care about the exponent on x you might wanna go like this:

([+-])?(\\d+(\\.\\d+)?)x(^(\d+))?

by the way, you don't need to escape + inside [], and - when it is next to [ of ].

2 Comments

thanks Sahand. (?<!(\\^|\\d|\\.))[+-]?(\\d+(\\.\\d+)?)(?!(x|\\d|\\.)) also works fine and gives 60.1. I still don't understand why (?!(x|\\d|\\.) works and group (?!x) doesn't work which was driving me nuts! since (?!x) means match (whatever you are matching) NOT followed by "x", right?. why do i need to or it with a digit or any character as you've put it with (?!(x|\\d|\\.). i would really appreciate if you shade some light. thanks a bunch.
when you say not followed by an "x", for example, the "55.6" inside "55.69x" would be a match for what you have described. since it is followed by a "9", not by an "x".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.