Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从字符串连接到格式化参数的自动转换_Java_Regex - Fatal编程技术网

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

Java 从字符串连接到格式化参数的自动转换,java,regex,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); (注意:我现在不担心获得正确的参数类型。我可以预处理文件以确定类型,或者转换为始终使用字符串。我现在不担心。) 我想知道是否有人已经解决了这个问题。我想出了这些正则表达

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

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
  • y
但是,考虑到它们如何连接在一起的所有可能性,我想不出一个好的方法来将它们重新组合在一起

也许这是错误的方法,我应该尝试退出,然后用format参数替换变量部分


有什么想法吗?谢谢。

如果要将所有内容替换为
%s
,可以执行以下操作: (注:假设代码格式良好,以空格表示)

保持从右到左的分辨率,因为参数位置很重要

1.)运行这个正则表达式来解析形式为
Log.d({something}+var)
Log.d({something},var)

替换

$1%s", $2$4
$1%s$4,$3,$5;
$1"%s$3,$2,$4
()

2.)现在,您需要注意字符串之间出现的每个变量:

继续运行此正则表达式,直到没有替换项出现:

(Log\.d\(.*)(\"\s*\+\s*([^\s]+)\s*\+\s*\")(.*?\"),([^\"]+);
替换

$1%s", $2$4
$1%s$4,$3,$5;
$1"%s$3,$2,$4
运行1后:

运行2后:

3.)最后,您需要解析包含前导变量的字符串-这没有问题:

(Log\.d\()([^\"]+)\s+\+\s*\"(.*?),([^"]+;)
替换

$1%s", $2$4
$1%s$4,$3,$5;
$1"%s$3,$2,$4

可能有一些案例没有涵盖,但它应该会给你一个想法


我将
Log.d
添加到匹配组及其替换部分,因此您可以使用
Log\(?:d | f | e)
如果您愿意,

您可以使用以下正则表达式一次性捕获所有参数和字符串。因此,您可以使用这些对来准确地找出参数在整个字符串中的位置

(?:(\w+)\s*\+\s*)?“((?:[^“\\]\124;\\)*+)”(?:\ s*\+\s*(\w+))”

(感谢提供改进版的。)

它将以以下格式查找作为Log.d一部分的所有连接:
[+][+]

其中,
[]
表示可选零件

这样,您就可以形成适当的替换,以下面的示例为例:

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.lang.StringBuilder;
import java.util.List;
import java.util.ArrayList;

class Main {
  public static void main(String[] args) {
    String log = "Log.d(\"Hello there \" + x + \", I see your are \" + y + \" years old!\");";
    System.out.println("Input: " + log);
    Pattern p = Pattern.compile("(?:(\\w+)\\s*\\+\\s*)?\"((?:[^\"\\\\]|\\\\.)*+)\"(?:\\s*\\+\\s*(\\w+))?");
    Matcher m = p.matcher(log);
    StringBuilder output = new StringBuilder(25);
    List<String> arguments = new ArrayList<String>(5);
    output.append("Log.d(\"");
    while (m.find()) {
        if (m.group(1) != null) {
            output.append("%s");
            arguments.add(m.group(1));
        }
        output.append(m.group(2));
        if (m.group(3) != null) {
            output.append("%s");
            arguments.add(m.group(3));
        }
    }
    output.append("\"");
    for (String arg : arguments) {
        output.append(", ").append(arg);
    }
    output.append(");");
    System.out.println("Output: " + output);
  }
}
import java.util.regex.Pattern;
导入java.util.regex.Matcher;
导入java.lang.StringBuilder;
导入java.util.List;
导入java.util.ArrayList;
班长{
公共静态void main(字符串[]args){
String log=“log.d(\'Hello there\'+x+\”,我看到你的年龄是\“+y+\”岁!\”;
System.out.println(“输入:“+log”);
模式p=Pattern.compile((?:(\\w+\\s*\\+\\s*)?\”((?:[^\“\\\\].*+)\(?:\\s*\\\\+\\s*(\\w+)))\”;
匹配器m=p.Matcher(对数);
StringBuilder输出=新StringBuilder(25);
列表参数=新的ArrayList(5);
output.append(“Log.d(\”);
while(m.find()){
如果(m.group(1)!=null){
输出。追加(“%s”);
添加(m.group(1));
}
输出追加(m.group(2));
如果(m.group(3)!=null){
输出。追加(“%s”);
添加(m.组(3));
}
}
output.append(“\”);
for(字符串参数:参数){
output.append(“,”).append(arg);
}
输出。追加(“);”;
System.out.println(“输出:”+输出);
}
}
输入:Log.d(“你好”+x+,我看到你是”+y+“岁!”)
输出:Log.d(“您好,这里是%s,我看到您已经%s岁了!”,x,y)


.

即使有正则表达式来翻译它,只要看一下
x
y
,你就无法(不检查逻辑)确定是否应该使用
%s
%d
-或其他任何东西。你如何知道如何使用
%s
%d
%f
?是,格式类型不是我现在担心的部分。我可以预处理文件并确定变量的类型。现在更多的是在正确的位置用限定符构造格式化字符串。嗯,也许是个愚蠢的想法。是否有机会将所有这些
Log.d
调用grep到一个文件中,并对它们进行排列,使它们能够编译并在您之前将变量设置为
%s
的上下文中执行,然后运行它,并以某种方式替换原始结果。如果存在转义的
\”
s,例如
Log.d(“值是\“+x+”\)
(?充其量只是一个补丁,因为它不知道在
之前有多少个
。对于字符串文字,应该使用正则表达式
”(?:[^“\]\124;\)*+“
@nhahdh在这种情况下,前面有多少个
”并不重要。”
。在引号之前只有奇数个反斜杠才是java中的有效字符串。但是如果您想彻底,我想您的方式最好。@nhahdh True,我稍后会调整我的解决方案。谢谢。基于您的重新编写的正则表达式:(不需要惰性量词-实际上所有量词都可以设为所有格,但我只设字符串字面所有格)感谢深思熟虑的回答。不幸的是,有两个。