java - 从字符串连接到格式化参数的自动转换

标签 java regex

我们的代码中到处都是这样的东西,

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/

相关文章:

java - 调用Java接口(interface)方法的困惑

java - 将图像转换为矩阵

java - 避免在 CyclicBarrier 上耍花招的想法

c++ - 如何循环 std::regex_search 的结果?

javascript - 如何替换脚本源中的url

java - 如何统计数组中每个单词的出现频率?

Java - For 循环将无法完成,仅三个循环后就会崩溃

java - 从字符串中获取多个int

regex - 正则表达式匹配字符串中 3 个字符后的文本

正则表达式在字符串中查找单词,替换新字符串中的单词(使用 Notepad++)