“静态”模式不应该总是静态的吗?

2022-09-01 10:43:12

我刚刚在一些我没有写的代码中发现了一个错误,我有点惊讶:

Pattern pattern = Pattern.compile("\\d{1,2}.\\d{1,2}.\\d{4}");
Matcher matcher = pattern.matcher(s);

尽管这个代码在我们得到的输入数据上严重失败(因为它试图以17.01.2011格式查找日期并取回10396 / 2011之类的东西,然后崩溃,因为它无法解析日期,但这真的不是这个问题的重点;我想知道:

  • Pattern.compile的要点之一不是速度优化(通过预编译正则表达式)吗?

  • 难道不应该把所有的“静态”模式编译成静态模式吗?

在网络上有很多例子,其中相同的模式总是使用Pattern.compile重新编译,我开始怀疑我是否看到了东西。

不是(假设字符串是静态的,因此不是动态构造的):

static Pattern pattern = Pattern.compile("\\d{1,2}.\\d{1,2}.\\d{4}");

总是比非静态模式引用更可取?


答案 1
  1. 是的,预编译a的全部意义在于只做一次。Pattern
  2. 这实际上取决于你将如何使用它,但一般来说,存储在字段中的预编译模式应该没问题。(与 s 不同,s 不是线程安全的,因此根本不应该存储在字段中,无论是否静态。staticMatcher

在静态初始值设定项中编译模式的唯一警告是,如果模式无法编译并且静态初始值设定项引发异常,则跟踪错误源可能会非常烦人。这是一个小的可维护性问题,但可能值得一提。


答案 2

首先,模式中的错误是因为点(.)与所有内容匹配。如果你想匹配点(.),你必须在正则表达式中转义它:

Pattern pattern = Pattern.compile("\\d{1,2}\\.\\d{1,2}\\.\\d{4}");

二是重法。始终建议只初始化一次静态模式(我的意思是未更改或未动态生成的模式)。实现此目的的常用方法之一是将 放入静态初始值设定项。Pattern.compile()Pattern.compile()

您可以使用其他方法。例如,使用单例模式或使用创建单例对象的框架(如 Spring)。