删除嵌套大括号之间的空间

删除嵌套大括号之间的空间

如何删除第一次出现(和最后一次出现之间的字符串之间的空格)。假设我有类似的字符串

(remove space ( fromthefile )between space).

我应该得到输出为

(removespace(fromthefile)betweenspace).

答案1

你可以用这种方式做到这一点,

 $ echo "(remove space ( fromthefile )between space)." | sed ':l s/\(([^ )]*\)[ ]/\1/;tl'
  (removespace(fromthefile)betweenspace).

这只会删除括号之间的空格。

另一个例子,

 $ echo "foo bar(remove space ( fromthefile )between space)." | sed ':l s/\(([^ )]*\)[ ]/\1/;tl'
 foo bar(removespace(fromthefile)betweenspace).

答案2

我不明白如何仅使用 sed 来完成此操作,因为普通的正则表达式不应该能够匹配 嵌套括号。幸运的是,像 Perl 这样的东西也支持不那么正则的表达式,就像从在这里回答

echo "out side (in ( side ( ) ) remove ( spaces ) ) out ( in again )." |
 perl -lpe 's/\(([^()]|(?R))*\)/ local $_ = $&; s,\s+,,g; $_ /eg'
out side (in(side())remove(spaces)) out (inagain).

(非)正则表达式的工作原理如下:

\(([^()]+|(?R))*\)
^^|      |    ||^^  -- literal parenthesis, inside of which:
  ^      ^    ^|   --- group with choice:
   ^^^^^^ ^^^^ |  ---- anything except parenthesis, any number,
               |       OR this whole pattern again.
               ^ ----- any number of those two choices

替换部分从 中获取匹配的字符串$&,在局部变量中修改它,删除所有空白字符,然后返回修改后的值。 (s///不适用于$&$1直接使用。)

不过,如果您知道一行上只有一组括号,那么会更容易,因此可以从第一个(到最后一个进行匹配)

echo "out (in ( side) here ) out again." | 
 perl -pe 's/\(.*\)/ $_ = $&; s,\s+,,g; $_ /e'
out (in(side)here) out again.

免责声明:我不知道$_在内部使用是否s///e会损坏,但它似乎对我有用。

相关内容