Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex only match if character is not included directly before desired string

Tags:

java

regex

I'm trying to solve this CodingBat problem:

Return true if the given string contains an appearance of "xyz" where the xyz is not directly preceeded by a period (.). So "xxyz" counts but "x.xyz" does not.

xyzThere("abcxyz") → true
xyzThere("abc.xyz") → false
xyzThere("xyz.abc") → true

I'm trying to solve this with a regex, but I'm unsure how to handle where the xyz is not directly preceeded by a period requirement.

My solution for the problem without the constraint is this:

public boolean xyzThere(String str) {
    return str.matches(".*xyz.*");
}

Any idea how to handle the said constraint with a regex?

like image 323
bob Avatar asked Nov 18 '12 16:11

bob


2 Answers

A negated character class should do the trick: str.matches(".*(?:^|[^.])xyz.*")

Here we're using a non capturing group (?:^|[^.]) to ensure that we match either at the start of the string ^, or at any position that isn't a period [^.]

like image 169
Kelvin Avatar answered Oct 08 '22 18:10

Kelvin


I personally used this solution, but there are quite a number of other variants:

str.matches("(.*[^.])?xyz.*")

I just make sure that if there is anything in front of xyz, then the period . does not immediately precede.

You can also write a look-behind solution:

str.matches(".*(?<!\\.)xyz.*");

(?<! ) part is negative lookbehind, and \\. (literal period) is the pattern that we want to check against.

like image 25
nhahtdh Avatar answered Oct 08 '22 20:10

nhahtdh