Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Java regex "matches" vs "find" get a different match when using non-greedy pattern? [duplicate]

Tags:

java

regex

So I ran into a bug caused by expecting the matches() method to find exactly the same match as using find(). Normally this is the case, but it appears that if a non-greedy pattern can be stretched to greedily accept the whole string, its allowed. This seems like a bug in Java. Am I wrong? I don't see anything in the docs which indicates this behavior.

Pattern stringPattern = Pattern.compile("'.*?'");
String nonSingleString = "'START'===stageType?'active':''";
Matcher m1 = stringPattern.matcher(nonSingleString);
boolean matchesCompleteString = m1.matches();
System.out.println("Matches complete string? " + matchesCompleteString);
System.out.println("What was the match? " + m1.group()); //group() gets the string that matched

Matcher m2 = stringPattern.matcher(nonSingleString);
boolean foundMatch = m2.find(); //this looks for the next match
System.out.println("Found a match in at least part of the string? " + foundMatch);
System.out.println("What was the match? " + m2.group());

Outputs

Matches complete string? true
What was the match? 'START'===stageType?'active':''
Found a match in at least part of the string? true
What was the match? 'START'

like image 912
Russell Leggett Avatar asked Jul 10 '14 16:07

Russell Leggett


1 Answers

This makes perfect sense.

The matches(...) method must attempt to consume the whole string, so it does, even with a non-greedy pattern.

The find(...) method may find a substring, so it stops at the point if finds any matching substring.

like image 174
Jamie Cockburn Avatar answered Nov 03 '22 11:11

Jamie Cockburn