替换数学函数的括号,留下其他括号

时间:2016-03-10 08:53:28

标签: ruby regex

如何编写正则表达式以括号替换数学函数的所有括号,但忽略所有其他括号?

以下是一些示例输入:

x(n)+(y(n)+1)*n
x(n(a,b),a,b)+2^(y(n(a,b)+a+b)+1)
x(n)+(y(n)/(N(n)))

我希望他们的相应输出为:

x[n]+(y[n]+1)*n
x[n[a,b],a,b]+2^(y[n[a,b]+a+b]+1)
x[n]+(y[n]/(N[n]))

这是我设法乱涂乱画的。

require 'rubygems'
require 'mechanize'
CSV.open('C:\Users\hp1\Desktop\output.txt', "wb") do |index|
    f = File.open('C:\Users\hp1\Desktop\input.txt', "r")
    f.each_line { |line|
        fn = line
        fn=fn.gsub(/(?[a-zA-Z0-9])\[+-*"/",]/, /[?[a-zA-Z0-9]]\[+-*"/",]/)
        index<<line
    end
 }
end

但它不起作用。

编辑:函数表示f(x)f(x,y)等格式的任何内容。非函数的格式为x+y,{{1}因此,需要将表达式x*y转换为f(x(y)+m(n)+(a+b))

3 个答案:

答案 0 :(得分:4)

只需使用一个简单的循环,并从里到外替换嵌套的括号对。

s = "x(n)+(y(n)+1)*n\nx(n(a,b),a,b)+2^(y(n(a,b)+a+b)+1)\nx(n)+(y(n)/(N(n)))\nf(x(y)+m(n)+(a+b))"

while  s.gsub!(/(\w+)\(([^()]+)\)/, '\1[\2]')
  s.gsub!(/(\W)\(([^()]+)\)/, '\1{\2}')
end

s.gsub!(/{/, "(")
s.gsub!(/}/, ")")

puts s
# x[n]+(y[n]+1)*n
# x[n[a,b],a,b]+2^(y[n[a,b]+a+b]+1)
# x[n]+(y[n]/(N[n]))
# f[x[y]+m[n]+(a+b)]

我假设任何单词字符序列后跟一个左括号是一个函数名。

需要在循环中将()临时替换为{}循环才能获得在函数参数内发生的分组括号。在完成所有功能替换f()f[]之后,这是相反的。

答案 1 :(得分:3)

我建议在 word 字符之后匹配所有嵌套(...)(甚至[a-zA-Z]后跟\w*匹配有效标识符),然后替换所有{{}在gsub块中包含([ )的内容。

请参阅regex demoIDEONE demo

]

在您的代码中:

strs = ['x(n)+(y(n)+1)*n', 'x(n(a,b),a,b)+2^(y(n(a,b)+a+b)+1)', 'x(n)+(y(n)/(N(n)))']
strs.each { |s| 
    puts s.gsub(/\b[a-zA-Z]\w*(\((?>[^()]|\g<1>)*\))/) { |m| m.gsub(/\(/,"[").gsub(/\)/,"]") }
}

结果:

fn=fn.gsub(/\b[a-zA-Z]\w*(\((?>[^()]|\g<1>)*\))/) { |m| m.gsub(/\(/,"[").gsub(/\)/,"]") }

正则表达式的解释:

  • x[n]+(y[n]+1)*n x[n[a,b],a,b]+2^(y[n[a,b]+a+b]+1) x[n]+(y[n]/(N[n])) - 一个单词边界,后跟一个ASCII字母,后跟零个或多个单词字符(\b[a-zA-Z]\w*
  • [a-zA-Z0-9_] - 第1组匹配:
    • (\((?>[^()]|\g<1>)*\)) - 文字\(
    • ( - 与(?>[^()]|\g<1>)*(以外的符号或整个第1组子模式匹配的原子组(子程序调用{​​{1}})
    • ) - 结束文字\g<1>

答案 2 :(得分:-1)

单独使用经典正则表达式是不可能的。数学表达式可以嵌套在无限深度,但正则表达式使用有限状态机。 (无限深度的概念当然是一种抽象。因此,帮助你决定不同的复杂性是非常有价值的。在实践中,这意味着你需要的“正常”正则表达式取决于嵌套你的多少级别愿意支持它。它可以很快失控。)

你需要类似堆栈的东西来存储开括号的数量,所以当出现一个右括号时,你需要以某种方式将它与开括号匹配,以决定它是否需要替换。

<强> 编辑: 我现在已经知道现代正则表达式(如ruby 2中)可以有递归子程序。有了这个,你应该能够解决嵌套问题。所以我的说法是不可能的不再是真的。