How to not capture a group in regex if it is followed by an another group

Viewed 49

If I have a string eg.: 'hcto,231' or 'hcto.12' I want to be able to capture 'o,231' or 'o.12' and process it as a number ('hct' is random and any other string can replace it). But I don't want to capture if the 'o' character if followed by a decimal number eg: 'wordo.23.12' or 'wordo,23,12'.

I've tried using the following regex:

([oO][.,][0-9]+)(?!([.,][0-9]+))

but it always matches. In the string 'hcto.22.23' it matches the bold part, but I don't want it to match anything. Is there a way to combine groups so it won't match if the negative lookahead is true.

1 Answers

The match occurs in hcto.22.23 because the lookahead triggers backtracking, and since [0-9]+ match match a single 2 (it does not have to match 22) the match succeeds and returns a smaller, unexpected match:

enter image description here

It seems the simplest way to fix the current issue is to make the dot or comma pattern in the lookahead optional, and remove unnecessary groups:

[oO][.,]\d+(?![.,]?\d)

See the regex demo.

Details

  • [oO] - o or O
  • [.,] - a dot or comma
  • \d+ - one or more digits
  • (?![.,]?\d) - not followed with ./, and a digit, or just with a digit.
Related