Skip to content Skip to sidebar Skip to footer

Match Single Character But Not Multiple

I have a RegExp like this one: /(?!xx)x.+?(?!xx)x/g There are three example strings that I test. I marked the expected matches with ^. Expectations: Should match 0-5: x...x ^^^^^

Solution 1:

I think this matches your intent.

^(?:(x[^x]{3}x)|x{2,}(x[^x]{3}x)x{2,})$

It is split into two parts, OR'd together:

(x[^x]{3}x) matches the case of exactly x...x

and x{2,}(x[^x]{3}x)x{2,} matches xxx...xxx but not xx...xx

Note: This does not help you for unbalanced matches. E.g. for example (xxx...xxxx) would still match the regex. However, as far as I know, you can't solve that problem with just a regex. You would need a stack to do so.

Solution 2:

If the leading number of times x should be the same as the trailing number times you could use a backreference to capturing group 1:

^(x*)(x[^x]+x)(\1)$

From the beginning of the string ^, capture in group 1 zero or more times an x. Then capture in group 2 an x, one or more times not an x followed by an x (x[^x]+x) using a negated character class. This group will contain your match.

At the end use a backreference \1 to match the same again as in group 1 and assert the end of the string $.

const strings = [
  "x...x",
  "xx...x",
  "xx...",
  "xx..xx",
  "xxx...xxx",
  "xxxx...xxxx",
];
let pattern = /^(x*)(x[^x]+x)(\1)$/;

strings.forEach((s) => {
  let res = s.match(pattern);
  if (res) {
    console.log(s + " --> " + s.match(pattern)[2]);
  } else {
    console.log(s + " --> no match.");
  }
});

Solution 3:

This captures every x...x except the one starting with two "xx" (xx...xx).

(?:^x{0}|x{2,})(x...x)

Post a Comment for "Match Single Character But Not Multiple"