0

I'm trying to match strings that do not fit the pattern name (CA) or barbaz (UK). I seem to have solved the problem using the answer here, but this is what I started with, and I'm wondering why it doesn't work:

var r1 = /^.+(?!\([A-Z]{2}\))$/;

r1.test('foo'); //true

r1.test('foo (US)'); //whoops -also true

From reading a negated lookahead doc I was hoping that any string that is not followed by e.g. (JP) would result in a match, while anything that is followed by e.g. (DE) would fail. (Only the former is being met).

I thought perhaps the .+ was kind of "consuming" everything, nullifying the lookahead, so I tried

r2 = /^[^()]+(?!\([A-Z]+\))$/;

r2.test('name (US)'); //false

r2.test('foo('); //whoops -also false

However I need things like foo( to match.

Why did my first attempt fail?

Community
  • 1
  • 1
KnewB
  • 353
  • 4
  • 16

1 Answers1

1

In your first expression, the .+ consumes the whole string and then the look-ahead is tested - it doesn't match, as there are no characters left. To achieve your goal you can use /^(?!.+\([A-Z]{2}\)$).+$/ - first checking the non-presence of the unwanted construct, then matching.

See https://regex101.com/r/aG7xZ0/1 with your samples

Sebastian Proske
  • 8,255
  • 2
  • 28
  • 37