Groovy:替换捕获组的惯用方法

9
我有一个字符串类似于这样:docker login -u username -p password docker-registry-url
我使用execute在Groovy脚本中执行该命令。为了调试目的,在执行之前,我打印出该命令,但由于它包含敏感数据,因此我混淆了用户名和密码。
def printableCmd = cmd.toString()

def m = printableCmd =~ /(?:.+) -u (.+) -p (.+) (?:.+)/

if (m.matches() && m[0].size() >= 3) {
  printableCmd = m[0][-1..-2].inject(m[0][0]) { acc, val -> acc.replaceAll(val, "***") }
}

以上代码按预期工作,并打印出 docker login -u *** -p *** docker-registry-url,但我想知道是否有更加惯用的方法来实现这一点。请注意,我不想删除捕获的组,只是用星号替换它们,从而清楚地表明该命令并没有错误,而是为了安全目的而被混淆。

2个回答

13
def cmd='docker login -u username -p password docker-registry-url'
println cmd.replaceAll(/(\s-[up]\s+)(\S+)/,'$1***')

输出:

docker login -u *** -p *** docker-registry-url

1

我自己使用正向后查找找到了以下解决方案:

​def cmd = "docker login -u username -p password docker-registry-url"
println cmd.replaceAll(/(?<=-[up]\s)(\S+)/,"***")

1
如果在“-u”和1个以上的非空白字符之间有2个或更多空格,则您的回溯方法将失败。捕获组方法是正确的方法。您可以使用“/(?<=-[up]\s{1,100})(\S+)/”,但这在Java正则表达式中是一个比较hacky的特性。 - Wiktor Stribiżew
1
@WiktorStribiżew 或许你指的是在Java中,回顾必须是已知长度,所以\s+不能使用。我使用了\s{1,10}。我之所以更喜欢这种方式而不是daggett的答案,是因为我认为它更清晰地表达了要求。 - Abhijit Sarkar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接