- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
TL;DR
Matcher
背后的设计决策是什么?的API?
背景
Matcher
有一种我没有预料到的行为,而且我找不到很好的理由。 API 文档说:
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 文档进一步说明的是:
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
在 (1)
处。为了解决这个问题,有必要调用 matches()
或其他将 Matcher
带入允许 group()
的状态的方法。以下作品:
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)
将 Matcher
设置为适当的状态以调用 group()
。
问题,可能没有建设性
为什么这个 API 是这样设计的?当 Matcher
是用 Patter.matcher(String)
构建时,为什么不自动匹配?
最佳答案
实际上,您误解了文档。第二次看你引用的陈述:-
attempting to query any part of it before a successful match will cause an IllegalStateException to be thrown.
如果没有找到匹配,匹配器可能会在访问 matcher.group()
时抛出 IllegalStateException
。
因此,您需要使用以下测试来实际启动匹配过程:-
- matcher.matches() //Or
- matcher.find()
以下代码:-
Matcher matcher = pattern.matcher();
只需创建一个 matcher
实例。这实际上不会匹配字符串。哪怕是一场成功的比赛。因此,您需要检查以下条件,以检查是否成功匹配:-
if (matcher.matches()) {
// Then use `matcher.group()`
}
如果 if
中的条件返回 false
,则表示没有匹配。所以,如果你使用 matcher.group()
而不检查这个条件,如果没有找到匹配,你会得到 IllegalStateException
。
假设,如果 Matcher
是按照您所说的方式设计的,那么您必须执行 null
检查以检查是否找到匹配项,然后调用matcher.group()
,像这样:-
你认为应该做的方式:-
// 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());
}
但是,如果你想打印任何进一步的匹配,因为一个模式可以在一个字符串中多次匹配,为此,应该有一种方法告诉匹配器找到下一个匹配。但是 null
检查将无法做到这一点。为此,您必须将匹配器向前移动以匹配下一个字符串。因此,在 Matcher
类中定义了各种方法来达到目的。 matcher.find()
方法匹配字符串,直到找到所有匹配项。
还有其他方法,以不同的方式 match
字符串,这取决于您要如何匹配。所以它最终在 Matcher
类上对字符串进行 matching
。 Pattern
类只是创建一个 pattern
来匹配。如果 Pattern.matcher()
要 match
模式,那么必须有一些方法来定义 match
的各种方式,如 matching
可以有不同的方式。所以,就需要 Matcher
类了。
所以,实际上是这样的:-
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 个匹配项,您的第一种方式将只打印第一个,而第二种方式将打印所有匹配项,方法是将 matcher
向前移动以匹配下一个模式。
我希望这能说清楚。
Matcher
的文档类描述了它提供的三种方法的使用,其中说:-
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.
The lookingAt method attempts to match the input sequence, starting at the beginning, against the pattern.
The find method scans the input sequence looking for the next subsequence that matches the pattern.
很遗憾,我找不到任何其他官方来源,明确说明为什么和如何这个问题。
关于java - 当没有调用 'matching' 方法时,Matcher 抛出 IllegalStateException 的理由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12911504/
我有一个坦克射击弹药的游戏。我对这部分代码的目标是检查它们是否与“碰撞”磁贴发生碰撞,如果是,则将其和磁贴移除。 代码如下所示,每 1/60 秒检查一次: Iterator iterator = sh
我尝试使用 JSR-303 注释(类级别)和验证器实现为 play 2.0.1 编写自定义表单验证器。 不幸的是,当我提交表单并且验证失败时,我收到了一个 IllegalStateException,
根据answer of BalusC ,我用过 FacesContext.getCurrentInstance().getExternalContext().redirect(url); 在我的 @P
这个问题已经有答案了: Copy a stream to avoid "stream has already been operated upon or closed" (10 个回答) 已关闭 5
这个问题已经有答案了: Spring: getOutputStream() has already been called for this response (3 个回答) 已关闭 4 年前。 我正
我正在尝试将 Activity 转换为 FragmentActivty 对象,以便获得 FragmentManager 对象 public class Main extends ListActivit
我正在尝试使用可编辑的组合框,通过用户的某些击键从数据库中快速搜索客户端的功能。我想要的是,用户将输入一些字母,如果这些字母与某些客户端匹配,这些客户端将保留在组合框的当前数据模型中。 代码如下。请修
这个问题已经有答案了: You need to use a Theme.AppCompat theme (or descendant) with this activity. Change to Th
我正在使用 Android Studio 和 Genymotion 作为模拟器创建一个应用程序,其中我在 3 个 EditText 中输入数据,当我单击按钮将其存储在 sqlite 数据库中时,它不起
我正在为 Android 构建一个简单的消息应用程序,并且在发送短信时遇到一些问题。我第一次使用 OnlickListener 时,消息被发送并显示在我的 ListView 中。当我在 Activit
我了解到 collect() 和 forEach() 都是流终端操作,在同一个流上调用它们会抛出 非法状态异常。但是,以下代码可以成功编译并按升序打印每个字符串的长度。不会引发任何异常。怎么会这样?
我对 classcastException 和非法状态异常都有点困惑,因为在大多数情况下它们看起来都很相似。 我在这个java代码中遇到了一个问题 class consumer {
我正在尝试这个小计算器程序。当我调用calculateResult()方法时,我想在第二个操作数为零且运算符为除法时显示IllegalStateException错误。但尽管如此,我在calculat
Stacktrace Here 导入java.util.*; 公共(public)类 AccountClient { public static void main(String[] args) {
我正在使用 readEntity() 方法读取 JAVAX 响应,但我收到以下堆栈跟踪: java.lang.IllegalStateException: Entity input stream ha
我是安卓新手。我正在尝试进行简单的登录 Activity ,但当我单击“登录”按钮时出现运行时错误。我认为我没有正确获取数据。我已经检查过,SQLite 中有一个与该 PK 相对应的数据。 日志猫。
我正在创建一个登录页面,工程师可以通过以“engg”开头的用户名登录。问题出在登录页面,当我使用正确的密码提供正确的输入时,它会给出“非法状态异常”。在错误的输入中,它工作正常。就像当我在我的 ora
我正在使用一些现有的 Java 设备驱动程序软件,该软件使用 JavaCOMM 进行串行 I/O。我昨天看到它抛出一个异常,其中有一个 IllegalStateException - 端口从 publ
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
我正在使用 Adventnet SNMPAPI 开发 UDP 监听程序。现在我需要将监听数据保存到数据库中。当我这样做时,我遇到了错误。任何人都可以帮忙解决这个问题吗... 这是我的代码。 impor
我是一名优秀的程序员,十分优秀!