我们的代码中到处都是这样的东西,
Log.d("Hello there " + x + ", I see your are " + y + " years old!");
我希望能够编写这样的转换脚本,
Log.d("Hello there %s, I see your are %d years old!", x, y);
(注意:我现在不担心获取正确的参数类型。我可以预处理文件以确定类型,或者转换为始终使用字符串。现在不是我关心的问题。)
我想知道是否有人解决了这个问题。我想出了这些正则表达式来提取字符串的静态和可变部分,
static final Pattern P1 = Pattern.compile("\\s*(\".*?\")\\s*");
static final Pattern P2 = Pattern.compile("\\s*\\+?\\s*([^\\+]+)\\s*\\+?\\s*");
通过在 find()
上循环,我可以找出每个部分,
- “你好”
- ", 我看到你是 "
- “岁!”
和,
- x
- 是
但考虑到将它们连接在一起的所有可能性,我无法想出一个好的方法将它们重新组合在一起。
也许这是错误的做法。我应该尝试退出,然后用格式参数替换可变部分吗?
最佳答案
如果您要将所有内容替换为 %s
,您可以这样做:
(ps.:假设在空格方面格式良好的代码)
继续从右向左解析,因为参数位置很重要。
1.) 运行此正则表达式将 Log.d({something} + var)
形式的所有内容解析为 Log.d({something}, var)
(Log\.d\(.*?)\"\s*\+\s*([^\s]+)(\+)?(\))
替换
$1%s", $2$4
( https://regex101.com/r/hY2iK6/8 )
2.) 现在,您需要注意字符串之间出现的每个变量:
继续运行这个正则表达式,直到没有替换出现:
(Log\.d\(.*)(\"\s*\+\s*([^\s]+)\s*\+\s*\")(.*?\"),([^\"]+);
替换
$1%s$4,$3,$5;
运行 1 后:https://regex101.com/r/hY2iK6/10
运行 2 后:https://regex101.com/r/hY2iK6/11
3.) 最后,您需要解析包含前导变量的字符串 - 这没问题:
(Log\.d\()([^\"]+)\s+\+\s*\"(.*?),([^"]+;)
替换
$1"%s$3,$2,$4
https://regex101.com/r/hY2iK6/9
可能有一些案例没有涵盖,但它应该给你一个想法。
我将 Log.d
添加到匹配组及其替换部分,因此您也可以使用 Log\.(?:d|f|e)
如果你喜欢,
关于java - 从字符串连接到格式化参数的自动转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31659435/