正则表达式匹配没有完全限定名称的类名

时间:2016-06-02 13:27:54

标签: java regex regex-negation regex-lookarounds

我正在使用Java编写代码生成器,而且我正在努力使用这个正则表达式。

我需要查找classname中的每个String sourceCode,并将其替换为fullyQualifiedClassName

使用以下代码......

String regex = "(?<=(^|\\n| |\\.))" + className + "(?=(<|\\.|\\())";
val = val.replaceAll(regex, fullyQualifiedClassName);

...我可以匹配每个classname

  • begin of lineline breakspace.(静态内部类的点)开头
  • <(通用),.(静态方法调用或静态内部类)或((新实例)
  • 结束

问题是如果sourceCode已经包含完全限定的类名,它将再次替换。例如:sourceCode包含java.util.Random,此内容将替换为java.util.java.util.Random

我试图找到一种方法来向正则表达式的第一部分添加一条规则:

  • 且不包含fullyQualifiedClassName.replace(className, "")

任何帮助都将非常感谢。

编辑一个例子,

这是一个愚蠢的例子,但它显示了遗漏的内容。

Random r = new java.util.Random();

在上面的代码中,当我拨打Random并且第二个replaceAll不应该匹配时,应该替换第一个Random

我在处理器代码中容易获得变量

String className = "Random";
String fullyQualifiedClassName = "java.util.Random";
String package = fullyQualifiedClassName.replace(className, "");

1 个答案:

答案 0 :(得分:1)

关键是完全限定名称不应以.开头。因此,您需要使用负面的lookbehind (?<!\.)。此外,\n 是空格,您可以将这些部分缩小为\s。在前瞻中,您还将单个字符与交替组匹配,而字符类更适合此任务。

所以,使用

String regex = "(?<=^|\\s)(?<!\\.)" + className + "(?=\\b|[<.(])";

请参阅regex demo

<强>解释&#34;

  • (?<=^|\\s) - 需要字符串开头或空格位于字符串当前位置之前的正面后视
  • (?<!\\.) - 如果.位于当前位置之前,则会导致匹配失败的负面观察
  • className - 类的变量(请注意,在这种情况下,您不必使用Pattern.quote,因为它应该只包含&#34; word&#34;字符)
  • (?=\\b|[<.(]) - 需要单词边界或<.(在课程名称后面的正向前瞻。