java比较两个Pattern对象

La *_*bla 9 java regex

有比较容易比较两个Pattern对象的方法吗?

我有一个Pattern使用正则表达式编译"//"来检查代码中的注释.

由于有几个正则表达式来描述注释,我想找到一种方法来区分它们.

怎么做到呢?在Pattern类没有实现的equals方法.

Ste*_*n C 7

你可以比较Pattern通过比较调用的结果对象pattern()toString但这你想要什么没有做(如果我正确地理解你的问题).具体来说,这会比较传递给Pattern.compile(...)工厂方法的字符串.

没有简单的方法可以测试两个不同的正则表达式是否相同.例如".+","..*"表示等效的正则表达式,但没有直接的方法来使用PatternAPI 来确定这一点.

(我甚至不知道这个问题在理论上是否可以解决......在一般情况下.)


我还想对接受的答案发表评论.作者提供了一些他声称显示 Pattern的equals方法继承自的代码Object.事实上,他所看到的输出与此一致 ......但它没有显示出来.

知道是否是这种情况的正确方法是查看javadoc ...其中equals方法列在继承方法列表中.这是确定的.

那么为什么这个例子没有显示作者所说的内容呢?

  1. 两种方法可能以相同的方式运行,但可以采用不同的方式实现.如果我们将该Pattern类视为黑盒子,那么我们就无法证明这种情况并未发生.(或者至少......不是没有使用反射.)

  2. 作者只在一个平台上运行它.其他平台可能表现不同.

在第二点,我的回忆是,在早期的Pattern(在Java 1.4中)实现中,这些Pattern.compile(...)方法保留了最近编译的模式对象1的缓存.如果您编译了两次特定模式字符串,则第二次可能会获得第一次返回的对象相同的对象.这将导致测试代码输出:

  true
  true
  true
  true
Run Code Online (Sandbox Code Playgroud)

但这表明了什么?它是否显示Pattern覆盖Object.equals?没有!

这里的教训是,你应该找出一个Java库法的行为主要是通过看的javadoc:

  • 如果你写了一个"黑匣子"测试,你可能会得出错误的结论......或者至少得出的结论可能不适用于所有平台.

  • 如果您的结论基于"阅读代码",那么您就有可能得出对其他平台无效的结论.


1 - 即使我的回忆不正确,这样的实现也会与Pattern.compile(...)方法的javadoc一致.他们并没有说每个compile调用都返回一个新Pattern对象.


Jir*_*era 5

也许我不完全理解这个问题.但正如您在以下示例中所看到的java.lang.Object.equals(Object),每个Java对象都有一个默认方法.此方法比较对象的引用,即使用==运算符.


package test;

import java.util.regex.Pattern;

public class Main {

  private static final Pattern P1 = Pattern.compile("//.*");
  private static final Pattern P2 = Pattern.compile("//.*");

  public static void main(String[] args) {
    System.out.println(P1.equals(P1));
    System.out.println(P1.equals(P2));
    System.out.println(P1.pattern().equals(P1.pattern()));
    System.out.println(P1.pattern().equals(P2.pattern()));
  }
}

输出:


true
false
true
true