11

Is it possible to know if a stream/string contains an input that could match a regular expression.

For example

 String input="AA";
 Pattern pat=Pattern.compile("AAAAAB");
 Matcher matcher=pat.matcher(input);
 //<-- something here returning true ?

or

 String input="BB";
 Pattern pat=Pattern.compile("AAAAAB");
 Matcher matcher=pat.matcher(input);
 //<-- something here returning false ?

Thanks

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
Pierre
  • 34,472
  • 31
  • 113
  • 192
  • 1
    That's not really how regex's work. The pattern should be a substring of the input, or there's no match. You could write your own thing that does the same, but it would be like a reverse regex. If you reverse your 'input' and 'pattern' strings, then call matcher.matches(input) - you'll get what you want. – Kylar Mar 26 '10 at 21:11

5 Answers5

13

Yes, Java provides a way to do that. First you have to call one of the standard methods to apply the regex, like matches() or find(). If that returns false, you can use the hitEnd() method to find out if some longer string could have matched:

String[] inputs = { "AA", "BB" };
Pattern p = Pattern.compile("AAAAAB");
Matcher m = p.matcher("");
for (String s : inputs)
{
  m.reset(s);
  System.out.printf("%s -- full match: %B; partial match: %B%n",
                    s, m.matches(), m.hitEnd());
}

output:

AA -- full match: FALSE; partial match: TRUE
BB -- full match: FALSE; partial match: FALSE
Alan Moore
  • 73,866
  • 12
  • 100
  • 156
8

Actually, you are in luck: Java's regex does have the method you want:

public boolean hitEnd()

Returns true if the end of input was hit by the search engine in the last match operation performed by this matcher.

When this method returns true, then it is possible that more input would have changed the result of the last search.

So in your case:

String input="AA";
Pattern pat=Pattern.compile("AAB");
Matcher matcher=pat.matcher(input);
System.out.println(matcher.matches()); // prints "false"
System.out.println(matcher.hitEnd());  // prints "true"
kowsikbabu
  • 499
  • 1
  • 6
  • 23
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
1

An alternative to hitEnd is to specify the requirement in the RE itself.

// Accepts up to 5 'A's or 5 'A's and a 'B' (and anything following)
Pattern pat = Pattern.compile("^(?:A{1,5}$|A{5}B)");
boolean yes = pat.matcher("AA").find();
boolean no = pat.matcher("BB").find();
nicerobot
  • 9,145
  • 6
  • 42
  • 44
0

Does Matcher.matches() not do what you want ?

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • He wants the reverse. His pattern is the longer string, he wants to find out of the input matches *so far*. – jwismar Mar 26 '10 at 21:29
-1

If you just want to check if a string contains some pattern specified by a regex:

String s = ...;
s.matches( regex )
Manuel Darveau
  • 4,585
  • 5
  • 26
  • 36