【问题标题】:Is java regex matcher stateful?java正则表达式匹配器是有状态的吗?
【发布时间】:2020-01-19 23:54:00
【问题描述】:

我来自python方面,对java regex不太了解,这个问题很容易解释,让我添加一些场景。

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

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

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

【问题讨论】:

    标签: java regex find matcher stateful


    【解决方案1】:

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

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

    groupVars用于记录抓包,每次Matcher#matchMatcher#find操作前都会重置。

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

    lastfind使用,它代表之前find操作的终端偏移量。

    如果你同时使用Matcher,这些局部变量会被不同的线程覆盖,这可能会导致意想不到的结果。

    【讨论】:

      【解决方案2】:
      1. 是的 Matcher 是有状态的。

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

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

        “这个类的实例不能安全地被多个并发线程使用。”

      4. 但是,像您的代码一样使用它应该可以工作...... 假设 Matcher 仅对当前线程可见/由当前线程使用,并且不会进一步使用(或下)调用堆栈。

      另见:


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


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

      【讨论】:

        猜你喜欢
        • 2011-01-24
        • 1970-01-01
        • 2015-09-02
        • 1970-01-01
        • 2011-03-30
        • 2011-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多