-1

right now i'm trying to learn how to use Matcher, Patterns and all that stuff, but i'm having a problem and i can't manage to solve it, i'm sure i'm doing something wrong but i don't know what, so i came here to ask for some help, here is my code:

public static void main(String[] args) {
    Pattern pattern = Pattern.compile("effect:([^:]*)(?::([^:]*))?(\\s)");
    Matcher matcher = pattern.matcher("effect:health:10 effect:speed:15 ");
    while (matcher.find()) {
        System.out.println(matcher.group(1));
        System.out.println(matcher.group(2));
    }
}

What im trying to make, is get from a string the effects and it's duration, but the effect duration isn't 100% necessary, right now the problem is that it does only detect the first effect, not the second one, it prints 'health' and '10', it needs an space at the end otherwhise it doesn't work, but if i remove '(\\s)' it won't work.

English isn't my native language, i tried to write this the best i could, if it have any misspelling i apologise.

MaTaMoR_
  • 23
  • 12

2 Answers2

2

First, since you don't seem to care about capturing the space, remove the capturing group about it.

Second, since the space may be optional, add a ?.

Now, this will cause trouble, because [^:] will consume the space, so also exclude spaces from the values being captured.

In reality, by doing that, you don't even need to match on the space at the end anyway, so remove it entirely.

Result:

Pattern.compile("effect:([^:\\s]*)(?::([^:\\s]*))?")

See result on regex101.


Since the regex find() will just skip over "bad" data, you may want to add extra guard conditions, e.g. if the input is "supereffect:a:b:c:d", do you want to match and return a/b, or should it skip that.

To skip that, you can add guard condition saying, that matched pattern must:

  • start at beginning or after a space: (?<=^|\\s)
  • end at end or with a space: (?=\\s|$)
Pattern.compile("(?<=^|\\s)effect:([^:\\s]*)(?::([^:\\s]*))?(?=\\s|$)")
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Okay after doing some test, it works fine, thanks for the help, thanks for the webpage, it's very useful. – MaTaMoR_ Mar 09 '16 at 17:39
  • @MaTaMoR_ I like regex101 because of the nice color coding and the explanation on the right, but be aware that it doesn't support Java regex. For full Java regex support, you need to use [regexplanet](http://www.regexplanet.com/advanced/java/index.html) – Andreas Mar 09 '16 at 17:46
  • Hey, sorry for bottering you, but i had another question, im trying to get the description, and i want it to be something like this : "description: Supp dude, second line," I don't know if is possible do it like this "description: Supp dude, second line Anyways the first option is enough, the problem is that i don't know what exactly i have to do, right now i got this code Pattern.compile("description:([^:,]*)"); But that will stop at the first comma, so i was wondering, how i can make it keep going till the last comma ? – MaTaMoR_ Mar 09 '16 at 19:42
  • @MaTaMoR_ That sounds like a different question, so you should create a new question for it, if you need help. – Andreas Mar 09 '16 at 20:39
0

I suppose you're looking for something like that:

final Pattern pattern = Pattern.compile("effect:([^\\s$:]+):?(\\d*)");
final Matcher matcher = pattern.matcher("effect:health:10 effect:speed:15 effect:none:");
while (matcher.find()) {
    System.out.println(matcher.group(1) + ": [" + matcher.group(2) + "]");
}

output:

health: [10]
speed: [15]
none: []
Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
  • It works when there is the simecolon, but for example if i try it with 'effect:speed' it doesn't work, is there a way to fix that ? – MaTaMoR_ Mar 09 '16 at 17:36