smeeb smeeb - 2 months ago 11
Java Question

Java regex not working for operand groups of possible values

I'm trying to write a Java method that will determine (true or false) if a particular String matches a regex of

animal<L_OPERAND,R_OPERAND>
, where
L_OPERAND
can be any of the following values:
dog
,
cat
,
sheep
and
R_OPERAND
can be any one of the following values:
red
,
blue
. All values are case- and whitespace-sensitive.

Some examples:

animal<fizz,cat> => false; fizz is not a valid L_OPERAND value
animAl<dog,blue> => false; animAl contains an upper-case char (illegal)
animal<dog,sheep> => false; sheep is not a valid R_OPERAND value
animal<dog, blue> => false; contains whitespace between ',' and 'blue' (no whitesapce allowed)
animal<dog,blue> => true; valid
animal<cat,red> => true; valid
animal<sheep,blue> => true; valid


My best attempt so far:

public class RegexExperiments {
public static void main(String[] args) {
boolean b = new RegexExperiments().isValidAnimalDef("animal<dog,blue>");
System.out.println(b);
}

public boolean isValidAnimalDef(String animalDef) {
String regex = "animal<[dog,cat,sheep],[red,blue]>";
if(animalDef.matches(regex)) {
return true;
} else {
return false;
}
}
}


Although I'm not getting any exceptions, I'm getting
false
for every type of input string (
animalDef
) I pass in. So obviously my regex is bad. Can anyone spot where I'm going awry?

Answer

Your problem lies within the [dog,cat,sheep] and [red,blue] structures. [] represent a character class, it matches a single character that is contained inside. For the first one this would be ,acdeghopst and for the second ,bdelru. So you currently match strings like animal<d,b> or even animal<,,,>.

What you are after is a mix of a grouping structure and an alternation. Alternations are provided by |, so e.g. dog|cat|sheep would match dog or cat or sheep. As you want this alternation inside a larger pattern, you have to contain it inside a group. The (for this case) simpliest grouping structure is a capturing group which is starting with ( and ending with ).

Your final pattern could then be animal<(dog|cat|sheep),(red|blue)>.