0

I have an input of 10+sqrt(10+(100*20)+20)+sqrt(5) which I need to be able to split up into sqrt(...) as many times as sqrt appears (in this instance, twice). The problem I am having is trying to split this up, I have tried on my own and come up with this (sqrt\()(?<=sqrt\()(.+?)(\)+) but regex only registers the first ) it comes across whereas I need it to find the closing bracket.

My REGEX attempt

As you can see in the picture the orange marker only covers up to the first bracket but i need it to end at the +20.

The desired output is a list as follows:

['10+', 'sqrt(', '10+(100*20)+20', ')', '+', 'sqrt(', '5', ')']

Thanks in advance

Ryszard Czech
  • 18,032
  • 4
  • 24
  • 37
Hunter
  • 321
  • 2
  • 11
  • 2
    Is regex really the perfect tool to achieve this? – CinCout Dec 20 '22 at 13:34
  • What would need to happen when you have `sqrt(5+sqrt(4*sqrt(1)+2)+3)`? – trincot Dec 20 '22 at 13:35
  • Second @cincout's comment. This is a parsing problem, not a regex problem. – The Lazy Graybeard Dec 20 '22 at 14:02
  • @trincot the desired output would be `['sqrt(5+sqrt(4*sqrt(1)+2)+3)']` as I'm using functions so it will separate that when running – Hunter Dec 20 '22 at 14:13
  • @Hunter I noticed my answer did not match your desired output. For a two steps working solution with [PyPI regex](https://pypi.org/project/regex/) see [this Python demo at tio.run](https://tio.run/##RY7dasMwDIXv/RSCXdhKhkkydjMYeZCmNV6qtilN7MluSZ8@U0JhF/rhSJzvxGe@hOljWYYxBs7AdKYZfJJFqQTfoOuqTL@cjUypqmgqLNfaxE/USr1BbWGYrtRnSGEk6C@efZ@JwYsSb0OGGIYpJyB7tnCfjsSpD4JgWhlMNt1/DOvNszPGtF@7A5p9YdoaWyxK7BD1O7B224vrGodOhIQrvrEviuD@zcFPR7Eew2Ndn0BjzNJvNJJEeaF3M5wCwyz55TfZzcdopxGGE8x7pSJLciM3hGX5Aw) – bobble bubble Dec 20 '22 at 15:45

2 Answers2

1

Here is a solution using the ast module from the standard library. I'm assuming the expression is valid Python.

# Import parser from Python standard library
import ast

# I have an expression to process
expression = '10+sqrt(10+(100*20)+20)+sqrt(5)'

# Parse it
tree = ast.parse(expression)

# Walk the parse tree
for node in ast.walk(tree):
    # Are we a function call?
    if isinstance(node, ast.Call):
        func = node.func
        # Are we a call to 'sqrt'?
        if expression[func.col_offset:func.end_col_offset] == 'sqrt':
            # We have what we want
            start = node.col_offset
            end = node.end_col_offset
            print(expression[start:end], start, end)

This outputs...

sqrt(5) 24 31
sqrt(10+(100*20)+20) 3 23
-3

You don't need to seperate the string. If you need to execute and return the result then, we can just use eval() to do it.


from math import *

query = "10+sqrt(10+(100*20)+20)+sqrt(5)"

print(eval(query))

# Output: 57.29158928177503

But if you need to just split the equation, we can use classic split(). Reason: It's easier to manage if we don't know no. of sqrt() in equation.

s = "10+sqrt(10+(100*20)+20)+sqrt(5)"

l = s.split('sqrt(')

d = [l[0]]

x = ''

for i in range(1, len(l)):

    if x: d.append(x)

    d.append('sqrt(')

    q = l[i]

    if i+1 == len(l): d.append(q)

    else:

        d.append(q[:-1])

        x = q[-1]



print(d)

# Output: ['10+', 'sqrt(', '10+(100*20)+20)', '+', 'sqrt(', '5)']

Peace!

Prabhas Kumar
  • 230
  • 10