【问题标题】:Regex to match class name without fully qualified name正则表达式匹配没有完全限定名的类名
【发布时间】:2016-06-02 13:27:54
【问题描述】:

我正在用 Java 编写代码生成器,但我正在努力处理这个正则表达式。

我需要找到String sourceCode 中的每个classname 并将它们替换为fullyQualifiedClassName

使用以下代码...

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

...我可以匹配每个classname

  • begin of lineline breakspace. 开头(点表示静态内部类)
  • &lt;(通用)、.(静态方法调用或静态内部类)或((新实例)结尾

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

我正在尝试找到一种方法,将一条规则添加到正则表达式的第一部分:

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

任何帮助将不胜感激。

编辑:一个例子,

这是一个愚蠢的例子,但它显示了缺少的东西。

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

在上面的代码中,当我调用replaceAll时,第一个Random应该被替换,第二个Random不应该匹配。

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

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

【问题讨论】:

  • 请提供一个可重现的例子。你应该使用否定的lookbehind断言。
  • @AvinashRaj 请查看编辑。我添加了一个例子。我正在寻找消极的后视镜,但努力让它发挥作用。
  • 我会尝试用"(?&lt;!\\.)\\b"替换lookbehind
  • @WiktorStribiżew 有什么理由吗?
  • 如果你的名字是完全限定的,它前面有一个.,不是吗?试试(?&lt;!\\.)\\bRandom(?=\\b|[&lt;.(])。或(?&lt;=^|\\s)(?&lt;!\\.)Random\\b(?=[&lt;.(]).

标签: java regex regex-negation regex-lookarounds


【解决方案1】:

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

所以,使用

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

regex demo

说明

  • (?&lt;=^|\\s) - 正向向后看,要求字符串的开头或空格正好在字符串中的当前位置之前
  • (?&lt;!\\.) - 如果. 正好在当前位置之前,则匹配失败
  • className - 类的变量(注意在这种情况下您不必使用Pattern.quote,因为它应该只包含“单词”字符)
  • (?=\\b|[&lt;.(]) - 正向前瞻,需要单词边界或 &lt;.( 紧跟在类名之后。

【讨论】:

    猜你喜欢
    • 2011-07-09
    • 2014-09-10
    • 2016-09-12
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    相关资源
    最近更新 更多