'How to include/exclude non-digits inside a string of numbers

Im trying to make a quadratic calculator for problems that follow ax^2 + bx + c = 0, but i want to include certain symbols (that being - in this case for if a number is negative) but exclude numbers followed by a certain symbol (that being ^ followed by 1 number afterwards (^2 for this case)). Ive already tried adding a second if statement and if/else statement. If it matters the code i am currently running is:

problem = input("give quadratic problem ")

new_string = ("{0}".format(problem))
 
emp_str = ""
for m in new_string:
    if m.isdigit():
        emp_str = emp_str + m
print(emp_str) 

print("The problem is {0}".format(problem))

im not very good with coding generally so there is a very big possibility there is something basic i am missing but any help is appriciated



Solution 1:[1]

This is easy to achieve using the re module(RegEx). Code:

import re
a = input("give quadratic problem ")
a = ' '+a
crit = re.compile(r"[^^](-\s*\d+\.?\d*|\d+\.?\d*)")
resarr = re.findall(crit, a)
resarr=[float(i.replace(' ', '')) for i in resarr]
print(resarr)

Output:

give quadratic problem 1.2x^2 - 2x - 3 = 0
[1.2, -2.0, -3.0, 0.0]

Edit:

Explaination of RegEx:

"[^^](-\s*\d+|\d+)"
[^^] -> rejects the match if it is preceded by a ^ sign to rule out exponents
Conditions:

  1. Negative numbers: -\s*\d+\.?\d* 
     First match the - sign
     Spaces in order to match even if - and the number have a space
     \d+ for the actual number
  2. Positive numbers: \d+\.?\d*
     Matches one or more successive digits(and a decimal followed by digits)
Note that the decimal is matched 0 or 1 times

Solution 2:[2]

You could use a regular expression with a negative lookbehind.

>>> expression = "1.2x^2 - 2x - 3 = 0"
>>> nums = re.findall(r"(?<!\^)(-?\s*\d+\.?\d*)", expression)
['1.2', '- 2', '- 3', ' 0']

Since this regex also includes a pattern for decimal points, you can also capture coefficients that aren't integers. Then, take out the spaces in each string, and convert it to a float:

>>> nums = [float(x.replace(' ', '')) for x in nums]
[1.2, -2.0, -3.0, 0.0]

Explanation of the regex (Try online):

(?<!\^)(-?\s*\d+\.?\d*)

(?<!  )                           : Negative lookbehind, make sure the string in the lookbehind doesn't exist before the match
    \^                            : This string is a caret
       (              )           : Capturing group
        -?\s*                     : Zero or one hyphens, followed by any number of whitespace...
              \d+\.?\d*           : ... followed by one or more digits, then an optional decimal point, then zero or more digits

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2