1

I have this code and I want to find both 1234 and 4321 but currently I can only get 4321. How could I fix this problem?

String a = "frankabc123 1234 frankabc frankabc123 4321 frankabc";
String rgx = "frank.* ([0-9]*) frank.*";
Pattern patternObject = Pattern.compile(rgx);
Matcher matcherObject = patternObject.matcher(a);
while (matcherObject.find()) {
    System.out.println(matcherObject.group(1));
}
KiwiFT
  • 105
  • 8
  • 1
    Your regex should be `frank.*? ([0-9]*) frank`, otherwise, the `.*` will eat up everything. – nhahtdh Mar 31 '14 at 21:38
  • Learn about [lazy vs greedy](http://stackoverflow.com/questions/2301285/what-do-lazy-and-greedy-mean-in-the-context-of-regular-expressions) quantifiers. – Boris the Spider Mar 31 '14 at 21:39
  • To elaborate on what @nhahtdh said, `*` is greedy by default, which means it will match the largest amount possible. Adding a `?` to it makes it non-greedy. – Mike B Mar 31 '14 at 21:39
  • Does 'frank' has to be part of the regexp or do you only want to get only "number" words? – wumpz Mar 31 '14 at 21:43

2 Answers2

2

Your regex is too greedy. Make it non-greedy.

String rgx = "frank.*? ([0-9]+) frank";
anubhava
  • 761,203
  • 64
  • 569
  • 643
1

Your r.e. is incorrect. The first part: frank.* matches everything and then backtracks until the rest of the match succeeds. Try this instead:

String rgx = "frank.*? ([0-9]*) frank";

The ? after the quantifier will make it reluctant, matching as few characters as necessary for the rest of the pattern to match. The trailing .* is also causing problems (as nhahtdh pointed out in a comment).

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521