Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.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 正则表达式问题-匹配API名称_Java_Regex_Matcher_Regex Lookarounds - Fatal编程技术网

Java 正则表达式问题-匹配API名称

Java 正则表达式问题-匹配API名称,java,regex,matcher,regex-lookarounds,Java,Regex,Matcher,Regex Lookarounds,我目前正在处理一个大型代码库,其中最近API的一个签名发生了更改。因此,我需要修改数千个文件以获得新功能。所以开发了一个java程序来获取所有*.java文件并查找旧的API模式。如果发现,请用新图案替换 旧API 新API 因此,我创建了一个正则表达式模式来匹配旧API,即API\[\d\s\.\w]*键[\.\w\s,]*\ 如果匹配,它将替换为 replaceString=matcher.group1++matcher.group2+ 因此,使用当前代码而不是预期的APIkey1、key4

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

旧API 新API 因此,我创建了一个正则表达式模式来匹配旧API,即API\[\d\s\.\w]*键[\.\w\s,]*\ 如果匹配,它将替换为

replaceString=matcher.group1++matcher.group2+

因此,使用当前代码而不是预期的APIkey1、key4,我得到了APIkey4。我已经分析了这个问题,我的推断是\w捕获了第一个密钥模式。如果我们需要比赛,我们需要做一个消极的展望


任何人都可以分享解决regex问题的最佳一致性方法吗?

类似于以下的方法应该可以奏效:

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

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

类似于以下内容的操作应该有效:

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

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

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需要一个真正的语法分析器,正则表达式无法完成这项复杂的工作,因为它们在词汇层面上工作——单词,而不是句子。

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需要一个真正的语法分析器,而正则表达式无法完成这项复杂的工作,因为它们在词汇层面上工作——单词,而不是句子。

您可能需要尝试,这允许您应用源代码转换

您可能需要尝试,这允许您应用源代码转换

为什么不@deprecate API3,Utils.50key1,key4表单,在内部调用新表单,然后重新编译呢?这个API是由另一个团队开发的,我们没有访问它的权限。为了向后兼容,API仍然存在。既然我们需要新功能,我们需要调用新方法为什么不@deprecate API3,Utils.50key1,key4表单,在内部调用新表单,然后重新编译?API是由另一个团队开发的,我们没有访问权限。为了向后兼容,API仍然存在。由于我们需要新功能,我们需要调用新方法。和之间的换行如何?@Aubin我替换了\s,这样字符类将匹配空格和制表符,而不是换行符,建议不错。和之间的换行如何?@Aubin我替换了\s,这样字符类将匹配空格和制表符,而不是换行符,好建议。我没有像你提到的第一个例子那样复杂的场景。但是第二个和第三个示例对我来说是有效的,这意味着由于代码格式的原因,API可以被分成多行。这种情况下,不情愿的量词方法*?很好。我们已经为空白字符合并了\s。我没有像您提到的第一个示例那样复杂的场景。但是第二个和第三个示例对我来说是有效的,这意味着由于代码格式的原因,API可以被分成多行。这种情况下,不情愿的量词方法*?很好。我们已经为空白字符合并了\s。+1:此解决方案在正确的抽象级别上解决问题我喜欢记录器模式并将尝试。+1:此解决方案在正确的抽象级别上解决问题我喜欢记录器模式并将尝试。