如果不在括号内,则拆分

时间:2015-12-26 05:22:48

标签: python regex

这个正则表达式问题困扰着我......

我想通过使用四个中的一个来分割字符串 基本的数学运算(+, - ,/,*),除非它存在于括号内。

Full:
'x^2 * ln(sin(x^2 + y^2)) + 8^(2*9)'

Full Goal:
['x^2', 'ln(sin(x^2 + y^2))', '8^(2*9)']
Simplified Problem:
'x^2 * sin(x^2 + y^2) + 8^(2*9)'

Simplified Goal:
['x^2', 'sin(x^2 + y^2)', '8^(2*9)']

完整或简化问题的解决方案可行。

2 个答案:

答案 0 :(得分:2)

正则表达式不能用于可靠地解决此问题。相反,请考虑使用一个非常简单的状态机来跟踪您是否在括号内,以确定是否应该拆分数学运算符。这是一个非常快速的尝试,似乎适用于您的输入。

math_ops = {'+', '-', '*', '/'}

def parse(inval):
    groups = []
    braces = 0
    part = ''
    for c in f:
        # We add to braces count 
        if c == '(':
            braces += 1
        # We subtract from braces count
        elif c == ')':
            braces -= 1
        # If we are at a math symbol and our brace count is 0, we have a complete part.
        if c in math_ops and braces == 0:
            groups.append(part.strip())
            part = ''
            continue
        part += c
    if part:
        groups.append(part)
    return groups

对于您的两个示例,输出为:

['x^2', 'ln(sin(x^2 + y^2))', ' 8^(2*9)']
['x^2', 'sin(x^2 + y^2)', ' 8^(2*9)']

答案 1 :(得分:1)

简化问题

def split(string):
    return re.findall(r'(?:[^+\-*/]|\(.*\))+', string)

你没有提到剥离空格,但你的例子确实如此。如果需要,

def split(string):
    return re.findall(r'(?! )(?:[^+\-*/]|\(.*\))+(?<! )', string)

完整问题

这是非regular language的经典示例,即无法通过有限状态机计算,这是正则表达式。一般而言,如果元素可以嵌套(例如,使用parens),则正则表达式是不充分的计算模型。你需要一个pushdown automaton或一个完整的图灵完整语言,比如Python。

def split(string):
    results = []
    depth = 0
    result = ''
    for c in string + '+':
        if c == '(':
            depth += 1
        elif c == ')':
            depth -= 1
        elif not depth and c in {'+', '-', '*', '/'}:
            results.append(result.strip())
            result = ''
            continue
        result += c
    return results