我目前正在使用大型代码库,最近其中一个API的签名发生了变化。所以我需要修改数千个文件才能获得新功能。因此开发了一个java程序来获取所有*.java
文件并查找旧的API模式。如果发现用新模式替换它。
API(3,Utils.FIFTY,key1,key4)
API(key1,key4)
所以我创建了一个正则表达式模式以匹配旧API API\([\d,\s\.\w]*(key[\.\w\s,]*)\)
如果匹配,则将其替换为
replaceString = matcher.group(1) + "(" + matcher.group(2) + ")";
因此,使用当前代码而非预期API(key1,key4)
,我得到的是API(key4)
。我已经分析了这个问题,我的推断是\w
抓住了第一个密钥模式。如果我们需要匹配,我们需要做一个消极的展望。
任何人都可以分享最一致的方法来解决正则表达式问题吗?
答案 0 :(得分:2)
F.J的答案与此测试案例不符:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class APIUpdater {
public static void main( String[] args ) {
String source = "\n" +
"API( key.getValue( 18 ),call( key1 ).mth(),key1,key4);\n" +
"API(\n" +
"\t3,\n" +
"\tUtils.FIFTY,\n" +
"\tkey1,\n" +
"\tkey4 );\n" +
"API(3,Utils.FIFTY,key1,key4);\n";
Pattern p =
Pattern.compile( "API\\([.\\w\\s,]*?,\\s*(key[\\.\\w\\s,]*)\\)" );
Matcher m = p.matcher( source );
while( m.find())
{
System.err.println( m.replaceAll( "API(key1,key4)" ));
}
}
}
输出是:
API( key.getValue( 18 ),call( key1 ).mth(),key1,key4);
API(key1,key4);
API(key1,key4);
多行上的调用不匹配,但正确处理了空格。
需要一个带语法的真正解析器来解析Java,正则表达式不能完成这个复杂的工作,因为它们在词汇层面工作(单词,而不是句子)。
答案 1 :(得分:1)
以下内容应该有效:
API\([\.\w \t,]*?,\s*(key[\.\w \t,]*)\)
此处的主要更改是将第一个字符类的重复从*
更改为*?
,这意味着它现在将匹配尽可能少的字符而不是尽可能多的字符,所以你您的所有key
参数都将包含在您的匹配组中。
答案 2 :(得分:1)
您可以尝试Recoder,它允许您应用源代码转换。