内联String.format调用的正则表达式 - 用字符串连接替换%s

时间:2018-01-15 14:52:41

标签: java regex refactoring

在我继承的代码库中,有人似乎喜欢String.format并编写如下代码:

String.format("%s: %s", message, e.getMessage())

我想用简单的字符串连接替换String.format调用,即

message + ": " + e.getMessage()

这当然可以用正则表达式加速搜索/替换,不是吗?

2 个答案:

答案 0 :(得分:0)

使用正则表达式实现此目标将具有挑战性。请考虑以下搜索/替换模式:

搜索:

String\.format\(\s*"([^%]*)%s([^%]*)%s([^%]*)",\s*([^,()]*),\s*([^,()]*)\)

替换:

"\1" + \4 + "\2" + \5 + "\3"

这些模式(及其变体)有几个问题:

  • 他们只使用固定数量的%s字符串进行替换。
  • 如果格式字符串以%s开头或结尾,则会生成空字符串。
  • 他们无法处理任意参数。在上面的表格中,只接受变量。包含e.getMessage()等方法调用的参数将无效。

你可以通过反复调整表达式来解决这些问题,但是如果这仍然可以让你保持工作,这是值得怀疑的。

如果你想尝试一下,我建议采用以下方法:

  1. 找到要处理的%s占位符数量最多的模式,并使搜索和替换模式适应所需的参数数量。
  2. 反过来,调整每个参数模式,使它们与您的参数匹配。例如,如果您使用e.getMessage()之类的简单方法调用参数,请将([^,()]*)模式替换为([^,()]*\(\))
  3. 继续使用一个%s占位符少的表达式。
  4. 删除所有连接的空字符串,将(+\s*"")|(""\s+)替换为空。

答案 1 :(得分:-2)

出于性能原因,我不建议这样做。

使用串联时,String池会快速填满,因为对于每次连接,都会创建一个String的新副本。