How are non-capturing groups, i.e., (?:), used in regular expressions and what are they good for?
How are non-capturing groups, i.e., (?:), used in regular expressions and what are they good for?
tl;dr non-capturing groups, as the name suggests are the parts of the regex that you do not want to be included in the match and ?: is a way to define a group as being non-capturing.
Let's say you have an email address example@example.com. The following regex will create two groups, the id part and @example.com part. (\p{Alpha}*[a-z])(@example.com). For simplicity's sake, we are extracting the whole domain name including the @ character.
Now let's say, you only need the id part of the address. What you want to do is to grab the first group of the match result, surrounded by () in the regex and the way to do this is to use the non-capturing group syntax, i.e. ?:. So the regex (\p{Alpha}*[a-z])(?:@example.com) will return just the id part of the email.
A Simple Answer
Use them to ensure one of several possibilities occur here (?:one|two) or an optional phrase camp(?:site)? or in general, anywhere you want to establish a group/phrase/section without needing to refer to it specifically.
They keep your captured group(s) count to a minimum.
Its extremely simple, We can understand with simple date example, suppose if the date is mentioned as 1st January 2019 or 2nd May 2019 or any other date and we simply want to convert it to dd/mm/yyyy format we would not need the month's name which is January or February for that matter, so in order to capture the numeric part, but not the (optional) suffix you can use a non-capturing group.
so the regular expression would be,
([0-9]+)(?:January|February)?
Its as simple as that.
(?: ... ) acts as a group ( ... ) but doesn't capture the matched data. It's really much more efficient than a standard capture group. It is use when you want to group something but don't need to reuse it later. @Toto
Let me take to you an example of geo coordinate, the below matches two groups
Latitude,Longitude
([+-]?\d+(?:\.\d+)?),([+-]?\d+(?:\.\d+)?)
Lets take one ([+-]?\d+(?:\.\d+)?)
co-ordinate can be whole number like 58 or could be 58.666
Hence the optional (.666) second part (\.\d+)? is mentioned.
(...)? - for optional
But it is parenthesised, that will be another group of match. and we dont want two matches one for 58 and another for .666, we need single latitude as match. Here comes non-capturing group (?:)
with non-capturing group [+-]?\d+(?:\.\d+)?, 58.666 and 58 both are single match
Open your Google Chrome devTools and then Console tab: and type this:
"Peace".match(/(\w)(\w)(\w)/)
Run it and you will see:
["Pea", "P", "e", "a", index: 0, input: "Peace", groups: undefined]
The JavaScript RegExp engine capture three groups, the items with indexes 1,2,3. Now use non-capturing mark to see the result.
"Peace".match(/(?:\w)(\w)(\w)/)
The result is:
["Pea", "e", "a", index: 0, input: "Peace", groups: undefined]
This is obvious what is non capturing group.