2

我目前正在处理一个大型代码库,最近其中一个 API 的签名发生了变化。所以我需要修改数千个文件才能获得新功能。所以开发了一个java程序来获取所有*.java文件并寻找旧的API模式。如果发现用新模式替换它。

旧 API

API(3,Utils.FIFTY,key1,key4)

新 API

API(key1,key4)

所以我创建了一个正则表达式模式来匹配旧 API,因为API\([\d,\s\.\w]*(key[\.\w\s,]*)\) 如果它匹配它将替换它

replaceString = matcher.group(1) + "(" + matcher.group(2) + ")";

因此,使用当前代码而不是预期API(key1,key4),我得到了API(key4). 我已经分析了这个问题,我的推断是\w捕获了第一个关键模式。如果我们需要匹配,我们需要做一个消极的展望。

任何人都可以分享解决正则表达式问题的最佳一致方法吗?

4

3 回答 3

2

FJ 的回答与这个测试用例不匹配:

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 需要具有语法的真正解析器,正则表达式无法完成这项复杂的工作,因为它们在词汇级别(单词,而不是句子)工作。

于 2013-02-20T19:22:30.200 回答
1

像下面这样的东西应该可以工作:

API\([\.\w \t,]*?,\s*(key[\.\w \t,]*)\)

这里的主要变化是将第一个字符类的重复从更改**?,这意味着它现在将匹配尽可能少的字符而不是尽可能多的字符,因此您的所有key参数都将包含在匹配组中。

于 2013-02-20T19:00:12.173 回答
1

您可能想尝试Recoder,它允许您应用源代码转换。

于 2013-02-20T19:43:26.503 回答