0

Regex to partition a polynomial expression

Hello, I'm looking for a regex (preferably in python) to dissect a polynomial expression into its monomials containing their signs like so: regex('x^6 + 3x^5- 4x^3 +5x-10') --> ['x^6', '+3x^5', '-4x^3', '+5x', '-10'] The plus signs could be omitted though. I tried this: (using regex module, not re) regex.split('\s?(\+|-)\s?', '3 + 2 -1+ 5') which gives ['3', '+', '2', '-', '1', '+', '5']

14th Apr 2020, 5:43 PM
Zuke
Zuke - avatar
6 ответов
+ 1
Haha, I'm certainly not a master at all. But your idea gave me an idea: string = 'x^6 + 3x^5- 4x^3 +5x-10' print(re.sub(r'\s?([+-])\s?', lambda x: ' -' if x.group(1) == '-' else ' ', string).split()) #['x^6', '3x^5', '-4x^3', '5x', '-10'] works for you. Can't comment on the complexity though :(
15th Apr 2020, 7:00 PM
Russ
Russ - avatar
+ 1
import re string = 'x^6 + 3x^5- 4x^3 +5x-10' print([i for i in re.findall(r'(?:-)?\d*(?:x(?:\^\d+)?)?', re.sub(r'([-])\s+', r'\1', string)) if i != '']) #['x^6', '3x^5', '-4x^3', '5x', '-10'] I would have liked not to have needed to use list comprehension here but there is no common feature between "x^6" and "-10". This means a few empty catches are made.
15th Apr 2020, 5:42 PM
Russ
Russ - avatar
+ 1
Russ I was doing something similar actually: regex.sub('\s?(\+|-)\s?', ' \1').split() The sub returns 'x^6 +3x^5 -4x^3 +5x -10' Then, splitting that gives the desired result (I already have a monomial processing regex). But I didn't want it to go through the string twice (even though inputs won't be so large). Guess I just have to respect the masters and say O(2n) = O(n) :D
15th Apr 2020, 6:17 PM
Zuke
Zuke - avatar
+ 1
Russ Thanks! I think we can make it more optimal. Do you know a regex that would return 'AC' even if B lies in the middle of A and C? re.findall(ignore_between_foo_and_bar, 'foo-anything-here-bar') -> ['foobar']
15th Apr 2020, 8:09 PM
Zuke
Zuke - avatar
+ 1
This what I have so far, not sure whether it's better than the other methods: >>> import re >>> pattern = '(\+|-)\s?([^+-]+)' >>> string = '+3x - 4x^2+7x^3 +6x -8x^2+ 3' >>> matches = re.finditer(pattern, string) >>> [match.group(1) + match.group(2) for match in matches] ['+3x ', '-4x^2', '+7x^3 ', '+6x ', '-8x^2', '+3']
15th Apr 2020, 9:16 PM
Zuke
Zuke - avatar
+ 1
Zuke I don't think there is a way to join A and C together into a single match group. Could be wrong though. I feel your latest attempt was similar to my original one using a single parse followed by a list comprehension. It could probably be improved if the spacing could be trusted to be consistent. I'm not sure you can do any better otherwise. (Or at least I can't!)
15th Apr 2020, 10:17 PM
Russ
Russ - avatar