mkczyk
mkczyk

Reputation: 2700

Regex multiple characters but without specific string

I have lines which consist of:

I want to capture string from each line which consist of:

Example lines:

ab123
ab 123
no abc123
no ab 123

I want to capture:

ab123
ab 123
abc123
ab 123

My regexp (works only for examples without "no ").

^
  (?! no \s) # not "no "
  ( # match it
    (?: \S{1,2} \s )? # optional: 1-2 non whitespace characters and one space, BUT NOT GET "no " (it doesn't works)
    \S+ # non whitespace characters
  )
$

Example online (4 unit tests): https://regex101.com/r/70soe2/1

Maybe should I use negative look ahead (?! no \\s) or negative look behind (?<! no \\s) in some way? But I don't know how to use it.

Upvotes: 2

Views: 270

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626903

You cannot actually rely on lookarounds here, you need to consume the optional no + whitespace part of the string.

It is best to use a non-capturing optional group at the start:

^
  (?: no \s)? # not "no "
  ( # capture it
    (?: \S{1,2} \s )? # optional: 1-2 non whitespace characters and one space, BUT NOT GET "no " (it doesn't works)
    \S+ # non whitespace characters
  )
$

See the regex demo

The value you need is inside Group 1.

If your regex engine supports \K construct, you may use this instead:

^
  (?:no \s \K)? # not "no "
  ( # match it
    (?: \S{1,2} \s )? # optional: 1-2 non whitespace characters and one space, BUT NOT GET "no " (it doesn't works)
    \S+ # non whitespace characters
  )
$

The \K in (?:no \s \K)? will omit the consumed string part from the match value, and you will get the expected result as a whole match value.

See the regex demo

Upvotes: 1

Related Questions