分割括号的内容而不分离括号ruby

时间:2015-05-26 21:01:28

标签: ruby regex

我目前正在开发一个ruby程序来计算术语。除了一件事:括号外,它完美无缺。我需要过滤内容或至少将内容放入数组中,但我已经尝试了一个小时来提出解决方案。这是我的代码:

splitted = term.split(/\(+|\)+/)

我需要一个数组而不是括号,例如:

"1-(2+3)" #=>["1", "-", ["2", "+", "3"]]

我已经尝试过了:

/(\((?<=.*)\))/

但它又回来了:

Invalid pattern in look-behind.

有人可以帮我这个吗?

更新

我忘了提一下,我的程序会拆分这个术语,我只需要括号的内容就是一个数组。

2 个答案:

答案 0 :(得分:0)

如果需要跟踪带有数组的括号层次结构,则不会仅使用正则表达式来管理它。你需要逐字解析字符串,并保留一堆表达式。

伪代码:

  • 表达式=新堆栈
  • 在堆栈上添加新数组
  • while string in string:
    • 如果单词是“(”:在堆栈上添加新数组
    • 否则,如果word是“)”:从堆栈中删除最后一个数组并将其添加到堆栈的(下一个)最后一个数组
    • 其他:将单词添加到堆栈的最后一个数组
  • 退出循环时,堆栈中应该只有一个数组(如果没有,则打开/关闭括号不一致)。

注意:如果您的最终目标是评估表达式,则可以节省时间并在Postfix aka Reverse-Polish Notation中解析字符串。 另请考虑使用off-the-shelf libraries

答案 1 :(得分:0)

解决方案取决于您在括号之间预期的模式,您尚未指定。 (例如,对于"(st12uv)",您可能需要["st", "12", "uv"]["st12", "uv"]["st1", "2uv"]等等。如果在您的示例中,它是一个自然数后跟一个+,后跟另一个自然数,则可以执行此操作:

str = "1-( 2+ 3)"

r = /
    \(\s*  # match a left parenthesis followed by >= 0 whitespace chars
    (\d+)  # match one or more digits in a capture group
    \s*    # match >= 0 whitespace chars 
    (\+)   # match a plus sign in a capture group
    \s*    # match >= 0 whitespace chars 
    (\d+)  # match one or more digits in a capture group
    \s*    # match >= 0 whitespace chars 
    \)       # match a right parenthesis
    /x

str.scan(r0).first
  => ["2", "+", "3"]

假设+可以是+-*/。然后你可以改变:

(\+)

为:

([-+*\/])

请注意,在字符类中,+无需转义,如果-是该类的第一个或最后一个字符,则无需转义.*(在这种情况下,它会不表示范围。)

顺便提一下,您收到错误消息“后台中的模式无效”,因为Ruby的外观不能包含可变长度匹配(即\K)。通过使用r = / \d+ # match one or more digits \K # forget everything previously matched [a-z]+ # match one or more lowercase letters /x "123abc"[r] #=> "abc" ,您可以使用正面的背后隐藏。例如,

/local/my_dir/project/src/qa/libs