Java pattern.matcher()与pattern.matches()的比较
我想知道,当提供相同的正则表达式和相同的字符串时,为什么java正则表达式pattern.matcher()和pattern.matches()的结果不同Java pattern.matcher()与pattern.matches()的比较,java,regex,Java,Regex,我想知道,当提供相同的正则表达式和相同的字符串时,为什么java正则表达式pattern.matcher()和pattern.matches()的结果不同 String str = "hello+"; Pattern pattern = Pattern.compile("\\+"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { System.out.println("I found the text
String str = "hello+";
Pattern pattern = Pattern.compile("\\+");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println("I found the text " + matcher.group() + " starting at "
+ "index " + matcher.start() + " and ending at index " + matcher.end());
}
System.out.println(java.util.regex.Pattern.matches("\\+", str));
上述结果如下:
I found the text + starting at index 5 and ending at index 6
false
我发现在匹配(“.\\+”
模式的情况下,使用表达式匹配完整字符串效果很好。matcher(string s)
返回可以在字符串s
中查找模式的匹配器<代码>模式。匹配(字符串str)
测试整个字符串(str
)是否与模式匹配
简言之(请记住区别):
-测试字符串是否包含-a模式pattern.matcher
-测试字符串是否为-a模式pattern.matches
Pattern.matches(字符串regex,字符序列输入)
将regex编译成Matcher
并返回Matcher.matches()
Matcher.matches
尝试根据模式(Regex)匹配整个区域(字符串)
因此,在您的例子中,
Pattern.matches(“\\+”,str)
返回一个false,因为str.equals(“+”)是false。Pattern.matches正在测试整个字符串,在您的例子中,您应该使用:
System.out.println(java.util.regex.Pattern.matches(".*\\+", str));
表示Javadoc中的任何字符串和+符号,请参见if(且仅当)整个区域部分
/**
*尝试根据图案匹配整个区域。
*
*如果匹配成功,则可以通过
*开始、结束和分组方法
*
*@return true当且仅当整个区域序列
*匹配此匹配器的模式
*/
公共布尔匹配(){
返回匹配(from,ENDANCHOR);
}
所以,如果您的字符串只是“+”,您将得到一个真实的结果。我认为您的问题应该是“我应该何时使用模式.matches()
方法?”,答案是“从不”。您是否希望它像.NET的matches
方法一样返回匹配的子字符串数组?这是一个完全合理的期望,但不,Java没有这样的期望
如果您只想进行快速而不精确的匹配,请在正则表达式的两端添加*
,并使用字符串自己的matches()
方法:
System.out.println(str.matches(".*\\+.*"));
如果您想提取多个匹配项,或者在之后访问有关匹配项的信息,请创建一个Matcher实例并使用其方法,就像您在问题中所做的那样Pattern.matches()。也就是说,它检查整个字符串是否为paten。
从概念上看,它会在模式的开头隐式地添加一个“^”,在模式的结尾隐式地添加一个$
对于String str=“hello+”,如果希望matches()返回true,则需要具有类似“\+”的模式
我希望这回答了你的问题
Matcher matcher = pattern.matcher(text);
在这种情况下,将返回matcher对象实例,该实例通过解释模式对输入文本执行匹配操作。然后我们可以使用,matcher.find()
来匹配输入文本中的模式数量
(java.util.regex.Pattern.matches("\\+", str))
这里,将隐式创建matcher对象,并返回一个布尔值,该布尔值将整个文本与模式匹配。这与字符串中的str.matches(regex)
函数的工作原理相同。与java.util.regex.Pattern.matches(“\\\+”,str)
等效的代码是:
Pattern.compile("\\+").matcher(str).matches();
方法find
将查找字符串中第一个出现的模式。实际上,find()
是不同之处。匹配器本身不是-Matcher.matches()
仍然返回false@Bozho是的,我知道。但是,由于OP正在比较一个返回Matcher
实例的方法和另一个返回布尔值的方法,并想知道为什么它们的结果不具有可比性,我决定写一个简单的答案,因为我知道我无法在SCJP考试中用它得分;-)您还掩盖了Pattern.matches
是一种静态方法这一事实。尝试在没有参数的情况下调用pattern.matches()
(pattern
是pattern
的一个实例),您的代码甚至不会编译。这个答案有误导性,pattern.matcher
不会测试字符串是否包含该模式,它会将整个字符串与该模式匹配,因此,与“hello world”
匹配的\w+
将为false,即使“hello world”
包含与\w+
匹配的子字符串。实际的区别在于静态性以及正则表达式的编译发生在哪里。这太尴尬了,让我来尝试解决这个问题。如果目标字符串是hello+world
,这取决于需要。在这种情况下,它将是:System.out.println(java.util.regex.Pattern.matches(“.\\\\+*”,str));这就是我一直在寻找的行为,它完全像String.matches(“regex”)
那样,只不过对于大型迭代来说要快得多。我发现它违反直觉,与其他语言不匹配。我经常在objective-c/java/swift/c#/vb.net之间移植代码。在我使用的所有其他语言中(据我记忆所及),速记语法搜索第一次出现的模式,从不尝试匹配整个字符串。毕竟,它会产生有时很难注意到的错误。
Pattern.compile("\\+").matcher(str).matches();