【问题标题】:Split if not within brackets如果不在括号内,则拆分
【发布时间】:2016-03-31 20:09:11
【问题描述】:

这个正则表达式问题难倒我...

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

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)']

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

【问题讨论】:

  • 如果括号的深度超过一个深度怎么办?
  • @AvinashRaj 很好。我从我的 IDE 错误地复制了我的问题。我已经编辑了问题以反映真正的问题。
  • 那么这个问题使用默认的 re 模块是无法解决的..

标签: python regex


【解决方案1】:

简化问题

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

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

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

全部问题

这是非regular language 的经典示例,即不能由有限状态机计算,这就是正则表达式。一般来说,如果元素可以嵌套(例如使用括号),则正则表达式是不充分的计算模型。您需要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

【讨论】:

  • 仅供参考,您需要附加字符以防碰到大括号,否则大括号会从结果中的段中删除。
  • 不要学究气,但 Python str 上没有 trim() 方法。你要找的方法是strip()
【解决方案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)']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 2021-12-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多