Use negative look-arounds regex to ensure pattern not surrounded by undesired characters.

I need to extract from text possible credit card numbers. I have regex for different types of credit cards from http://www.richardsramblings.com/regex/credit-card-numbers/. But if the match preceded or followed by any digit, it is not considered as a valid credit card number, but just as unrelated number.
I’ve tried to add non-capturing group (?:\D|) before and after expected card regex,e.g
(?:\D|^)(?:(?:(?:(4[0-9]{12}(?:[0-9]{3})?))|(3[47][0-9]{13}))(?:\D|$))
It mostly works OK, but if 2 credit cards are next to each other, separated by single character:
 4740515144050,378282246310005
the first card matched, but the second is not found.
Negative lookahead is indispensable if you want to match something not followed by something else.
So I was able to search what I need using negative look-arounds: negative lookbehind (?<!\d) before the expression and negative lookahead (?!\d) after the expression
(?<!\d)(?:(?:(?:(4[0-9]{12}(?:[0-9]{3})?))|(3[47][0-9]{13})|(?:5[1-5][0-9]{14}))(?!\d))
See my example of regex in https://regex101.com/r/iY2aR6/8

 

I want to clarify that the purpose of non-capturing groups is different to look-arounds .
In regex, normal parentheses not only group parts of a pattern, they also capture the sub-match to a capture group.  At other times, you do not need the overhead.
If you need parentheses to work in natural way to only group parts of a pattern, you need to specify non-capturing group by putting ?: after opening parenthesis

#lookahead, #lookbehind, #non-capturing-group