java 正则表达式匹配器是有状态的吗?

Is java regex matcher stateful?

我来自python方面,对java正则表达式了解不多,这个问题很容易解释,让我添加一些场景。

假设我有一个带有 Matcher matcher 变量的实例,以及一个像这样的函数:

public String getMatch(String group) {
    if (matcher.find()) {
        return matcher.group(group);
    } else { blah }
}

所有正则表达式捕获组都已命名,多次调用它会导致问题吗?

Pattern 是线程安全的,但 Matcher 不是。

Matcher 维护一些局部变量,如 groupVarslocalVarslast

groupVars用于记录组捕获,在每次Matcher#matchMatcher#find操作前会被重置。

localVars用于记录匹配操作的上下文

lastfind使用,表示前面find操作的终端偏移量

如果您并发使用Matcher,这些局部变量将被不同的线程覆盖,这可能会导致意外结果。

  1. Matcher 是有状态的。

  2. 如果 anything1 在您调用 findmatch 时(仍然) 查看上一次通话的组(等),那么您将失去上一次通话的状态。 resetreset(CharSequence) 以及其他一些方法也是如此。这种行为是 API 设计中固有的,并且有明确的记录。

  3. Matcher 不是线程安全的。 javadoc 明确指出:

    "Instances of this class are not safe for use by multiple concurrent threads."

  4. 但是,像您的代码一样使用它应该可以工作...提供 Matcher 仅对当前用户可见/使用线程,而不是在调用堆栈的上方(或下方)进一步使用。

另请参阅:

  • Java Pattern Matcher: create new or reset? ...虽然接受的答案缺少 "recursion" 警告。

相比之下,Pattern 既线程安全又不可变/无状态。


1 - 这可能是另一个线程,或者在调用堆栈的不同点使用相同 Matcher 的当前线程;即通过递归或类似的东西。