Change your (.*)
to ([^_]*)
. This will create a character class of anything but _
, and match it 0+ times. This way _
never gets counted as a capture group, but only a delimiter. Also, _
is not a reserved character so it does not need to be escaped. Final expression:
^(dw|lat)_([^_]*)_(Paid-Search|Text-Ad)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)_([^_]*)$
Update:
If you don't need your last 8 capture groups to be matched, you can clean up this expression even further:
^(dw|lat)_([^_]*)_(Paid-Search|Text-Ad)(?:_[^_]*){8}$
This just takes the last pattern and repeats it 8 times. However, if you try to capture the [^_]*
, it will only remember the last occurrence as your 4th capture group (rather than remembering all 8).