当没有调用“匹配”方法时,Matcher抛出IllegalStateException的原理 [英] Rationale for Matcher throwing IllegalStateException when no 'matching' method is called

查看:132
本文介绍了当没有调用“匹配”方法时,Matcher抛出IllegalStateException的原理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR

Matcher 的API?

What are the design decisions behind Matcher's API?

背景

Matcher 有一种我没想到的行为,我找不到合理的理由。 API文档说:

Matcher has a behaviour that I didn't expect and for which I can't find a good reason. The API documentation says:


创建后,匹配器可用于执行三种不同的匹配操作:
[。 ..]
这些方法中的每一个都返回一个表示成功或失败的布尔值。可以通过查询匹配器的状态来获得有关成功匹配的更多信息。

Once created, a matcher can be used to perform three different kinds of match operations: [...] Each of these methods returns a boolean indicating success or failure. More information about a successful match can be obtained by querying the state of the matcher.

API文档的进一步说法是:

What the API documentation further says is:


匹配器的显式状态最初是未定义的;在成功匹配之前尝试查询它的任何部分将导致抛出IllegalStateException。

The explicit state of a matcher is initially undefined; attempting to query any part of it before a successful match will cause an IllegalStateException to be thrown.

示例

String s = "foo=23,bar=42";
Pattern p = Pattern.compile("foo=(?<foo>[0-9]*),bar=(?<bar>[0-9]*)");
Matcher matcher = p.matcher(s);
System.out.println(matcher.group("foo")); // (1)
System.out.println(matcher.group("bar"));

此代码抛出

java.lang.IllegalStateException: No match found

at (1)。要解决这个问题,有必要调用 matches()或将匹配器带入一个状态的其他方法允许 group()。以下作品:

at (1). To get around this, it is necessary to call matches() or other methods that bring the Matcher into a state that allows group(). The following works:

String s = "foo=23,bar=42";
Pattern p = Pattern.compile("foo=(?<foo>[0-9]*),bar=(?<bar>[0-9]*)");
Matcher matcher = p.matcher(s);
matcher.matches(); // (2)
System.out.println(matcher.group("foo"));
System.out.println(matcher.group("bar"));

添加对 matches() (2)匹配器设置为正确状态以调用 group()

Adding the call to matches() at (2) sets the Matcher into the proper state to call group().

问题,可能不具有建设性

为什么是这个API设计得像这样吗?当 Matcher 使用 Patter.matcher(String)构建时,为什么不自动匹配?

Why is this API designed like this? Why not automatically match when the Matcher is build with Patter.matcher(String)?

推荐答案

实际上,你误解了文档。再看看你引用的陈述: -

Actually, you misunderstood the documentation. Take a 2nd look at the statement you quoted: -


在成功匹配之前尝试查询它的任何部分会导致
抛出IllegalStateException。

attempting to query any part of it before a successful match will cause an IllegalStateException to be thrown.

匹配器在访问<时可能会抛出 IllegalStateException code> matcher.group()如果未找到匹配项。

A matcher may throw IllegalStateException on accessing matcher.group() if no match was found.

因此,您需要使用以下测试来实际启动匹配过程: -

So, you need to use following test, to actually initiate the matching process: -

 - matcher.matches() //Or
 - matcher.find()

以下代码: -

Matcher matcher = pattern.matcher();  

只需创建匹配器实例。这实际上不匹配字符串。即使有成功的比赛。
因此,您需要检查以下条件,检查是否成功匹配: -

Just creates a matcher instance. This will not actually match a string. Even if there was a successful match. So, you need to check the following condition, to check for successful matches: -

if (matcher.matches()) {
    // Then use `matcher.group()`
}

如果中的条件返回 false ,则表示没有匹配。因此,如果您使用 matcher.group()而不检查此条件,如果匹配不是,您将获得 IllegalStateException 找到。

And if the condition in the if returns false, that means nothing was matched. So, if you use matcher.group() without checking this condition, you will get IllegalStateException if the match was not found.

假设,如果匹配器的设计方式与你相同说,然后你必须做一个 null 检查以确定是否找到匹配,调用 matcher.group(),如下所示: -

Suppose, if Matcher was designed the way you are saying, then you would have to do a null check to check whether a match was found or not, to call matcher.group(), like this: -

您认为应该采取的方式: -

// Suppose this returned the matched string
Matcher matcher = pattern.matcher(s);  

// Need to check whether there was actually a match
if (matcher != null) {  // Prints only the first match

    System.out.println(matcher.group());
}

但是,如果你想打印任何进一步的比赛,因为一个模式可以在String中多次匹配,为此,应该有一种方法告诉匹配器找到下一个匹配。但是 null 检查将无法做到这一点。为此,您必须向前移动匹配器以匹配下一个String。因此, Matcher 类中定义了各种方法来实现此目的。 matcher.find()方法匹配字符串,直到找到所有匹配项。

But, what if, you want to print any further matches, since a pattern can be matched multiple times in a String, for that, there should be a way to tell the matcher to find the next match. But the null check would not be able to do that. For that you would have to move your matcher forward to match the next String. So, there are various methods defined in Matcher class to serve the purpose. The matcher.find() method matches the String till all the matches is found.

还有其他方法,以不同的方式匹配字符串,这取决于你想要匹配的方式。因此它最终在 Matcher 类中对字符串执行匹配 Pattern 类只是创建一个模式来匹配。如果 Pattern.matcher()匹配模式,那么必须有一些方法来定义各种方式到匹配,因为匹配可以有不同的方式。所以,需要匹配类。

There are other methods also, that match the string in a different way, that depends on you how you want to match. So its ultimately on Matcher class to do the matching against the string. Pattern class just creates a pattern to match against. If the Pattern.matcher() were to match the pattern, then there has to be some way to define various ways to match, as matching can be in different ways. So, there comes the need of Matcher class.

所以,它实际上是这样的: -

Matcher matcher = pattern.matcher(s);

   // Finds all the matches until found by moving the `matcher` forward
while(matcher.find()) {
    System.out.println(matcher.group());
}

所以,如果在字符串中找到4个匹配项,那么第一种方式,将仅打印第一个,而第二个方式将打印所有匹配,通过移动匹配器前进以匹配下一个模式。

So, if there are 4 matches found in the string, your first way, would print only the first one, while the 2nd way will print all the matches, by moving the matcher forward to match the next pattern.

我希望能说清楚。

Matcher 类描述了它提供的三种方法的使用,说: -

The documentation of Matcher class describes the use of the three methods it provides, which says: -


通过调用模式的匹配器
方法从模式创建匹配器。一旦创建,匹配器可用于执行三种不同的
种匹配操作:

A matcher is created from a pattern by invoking the pattern's matcher method. Once created, a matcher can be used to perform three different kinds of match operations:


  • 匹配方法尝试将整个输入序列
    与模式匹配。

  • The matches method attempts to match the entire input sequence against the pattern.

lookingAt方法尝试匹配输入序列,从头开始
反对模式。

The lookingAt method attempts to match the input sequence, starting at the beginning, against the pattern.

find方法扫描输入序列,寻找与模式匹配的下一个
子序列。

The find method scans the input sequence looking for the next subsequence that matches the pattern.

不幸的是,我找不到任何其他官方消息来源,说明确地为什么 这个问题。

Unfortunately, I have not been able find any other official sources, saying explicitly Why and How of this issue.

这篇关于当没有调用“匹配”方法时,Matcher抛出IllegalStateException的原理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆