使用Ruby替换嵌套表达式

使用Ruby替换嵌套表达式,ruby,regex,Ruby,Regex,如何在保留空格和其他字母的同时,仅替换下面表达式中括号之间的x: { x} x {abc x efg} x x {} { x{x}{ x} } 不同于,因为括号内有括号。最简单的方法(使用regex)是匹配括号最外面的表达式,然后在替换回调中替换x: > '{ x} x {abc x efg} x x {} { x{x}{ x} }'.gsub(/\{(?:[^{}]|\g<0>)*\}/) {|s| s.gsub('x', 'y')} => "{ y} x {ab

如何在保留空格和其他字母的同时,仅替换下面表达式中括号之间的x:

{ x} x {abc x efg} x x {} { x{x}{  x} }
不同于,因为括号内有括号。

最简单的方法(使用regex)是匹配括号最外面的表达式,然后在替换回调中替换
x

> '{ x} x {abc x efg} x x {} { x{x}{  x} }'.gsub(/\{(?:[^{}]|\g<0>)*\}/) {|s| s.gsub('x', 'y')}
=> "{ y} x {abc y efg} x x {} { y{y}{  y} }"
'{x}x{abc x efg}x{x{x}{x}'.gsub(/\{(?:[^{}]\g)*\}/){s | s.gsub('x','y'))
=>“{y}x{abc y efg}x{}{y{y}{y}}”
此解决方案的核心是在这个正则表达式中匹配最外层括号中的表达式:

/\{(?:[^{}]|\g<0>)*\}/
/\{(?:[^{}]\g)*\}/
暂时扔掉
\g
分支,我们有
\{(?:[^{}]-))*\}
。这将匹配
{
,后跟任何数量的非
{
}
字符,然后是
}

\g
将递归到整个表达式本身。这增加了一种可能性,即在
{
}
之间,它可以包含任意数量的括号内表达式,而括号内的表达式又可以包含非括号字符和更多括号内的表达式

上面的正则表达式将匹配字符串中的
{x}
{abc x efg}
{}
{x{x}}
,然后可以在替换回调中替换这些
x


我不确定,但我认为在没有替换回调的情况下,无论如何都无法做到这一点。即使存在,也不会是一个实用的解决方案。

最简单的方法是将最外括号表达式与递归正则表达式相匹配,然后在替换回调函数中进行大量替换。如果您的真实世界任务更复杂,您可能需要考虑使用PARSLET、CaluSUs创建给定语法的解析器。或者树梢。如果这只是一项一次性的任务,那么这些可能是过火了。