sed 命令仅替换匹配的括号内的内容

sed command to replace only what's inside a matching set of parentheses

我有一些看起来像 OldUtility.getList(obj) 的旧代码已被重构为 obj.getList()。我正在尝试编写一个 sed 命令来正确重构我的代码。到目前为止,我拥有的是:

sed -i '' 's/\(OldUtility.getList(\)\(.*\))/.getList()/g'

这个问题是它贪婪地抓住了最后一个右括号。这意味着像下面这样的情况不起作用:
OldUtility.getList(obj).size()

someFunc(OldUtility.getList(obj), otherObj.otherFunc())

但我不希望它是非贪婪的,因为它还需要处理像这样的情况:
OldUtility.getList(otherObj.toObj())->otherObj.toObj().getList()

所以问题是如何让 </code> 成为 <code>OldUtility.getList(...) 括号内的所有内容?

如果您不想捕获右括号,您应该使用 [^)]* 而不是 .*

用这个测试:

echo "OldUtility.getList(otherObj.toObj()) OldUtility.getList(obj).size() someFunc(OldUtility.getList(obj), otherObj.otherFunc())" | sed -E 's/OldUtility.getList.([^)]*)\)([\)]*)/.getList()/g'

命令是sed -E 's/OldUtility.getList.([^)]*)\)([\)]*)/.getList()/g'.

你让它变得比需要的更复杂。

$ echo "OldUtility.getList(obj)" | sed -r 's/(OldUtility.getList\()[^)]*\)/)/'

OldUtility.getList()

我想我误读了参数提取的问题

$ echo "OldUtility.getList(obj)" | sed -r 's/OldUtility(.getList\()([^)]*)\)/)/'

obj.getList()

最好从搜索模式中捕获字符串值以消除拼写错误并将这些值包含在一个地方。

看来我又漏了一个。 这会处理更多级别,但对于 sed 来说在没有前瞻的情况下处理起来会变得复杂。

$ echo "OldUtility.getList(otherObj.toObj())" | 
  sed -r 's/OldUtility(.getList\()([^)]+(\(\))?)//'

otherObj.toObj().getList()

由于getList(...)可能多次包含任何级别的嵌套括号,您不能用sed 解决这个问题(无法知道哪个右括号是好的)。这是一个可以与 Perl 一起使用的模式(具有匹配嵌套括号的功能):

OldUtility\.getList\(([^()]*+(?:\((?1)\)[^()]*)*+)\)

详情:

OldUtility\.getList\( # Note that the literal dot and parenthesis must be escaped
(            # open capture group 1
    [^()]*+  # all that is not a parenthesis (zero or more)
    (?:           # open a non capturing group
        \((?1)\)  # recursion with the capture group 1 subpattern
        [^()]*
    )*+           # repeat the non-capturing group (zero or more times)
)
\)

示例:

echo 'OldUtility.getList(otherObj.toObj().toString())' | perl -pe 's/OldUtility\.getList\(([^()]*+(?:\((?1)\)[^()]*)*+)\)/.getList()/g'