Como é que os grupos não capturadores, ou seja, (?:)
, são utilizados em expressões regulares e para que servem?
?:
é utilizado quando você quer agrupar uma expressão, mas você não quer salvá-la como uma porção de cordas combinadas/capturadas.
Um exemplo seria algo que correspondesse a um endereço IP:
/(?:\d{1,3}\.){3}\d{1,3}/
Note que eu não me importo em salvar os primeiros 3 octetos, mas o (?:....)
agrupamento permite-me encurtar o regex sem incorrer na sobrecarga de capturar e armazenar um fósforo.
Isso torna o grupo não-capturado, o que significa que o substrato combinado por esse grupo não será incluído na lista de captações. Um exemplo em rubi para ilustrar a diferença:
"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]
Grupos que captura você pode usar mais tarde no regex para combinar OU você pode usá-los na parte de reposição do regex. Fazer um grupo não-capturar simplesmente isenta esse grupo de ser usado por qualquer uma destas razões.
Grupos não capturadores são ótimos se você estiver tentando capturar muitas coisas diferentes e há alguns grupos que você não quer capturar.
Essa é praticamente a razão pela qual eles existem. Enquanto você está aprendendo sobre grupos, aprenda sobre Grupos Atômicos, eles fazem muito! Há também grupos de aparência, mas eles são um pouco mais complexos e não são muito usados.
Exemplo de utilização mais tarde no regex (backreference):
<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>
[ Encontra uma tag xml (sem ns suporte) ]
([A-Z][A-Z0-9]*)
é um grupo de captura (neste caso é o nome da tagname)
Mais tarde no regex é \1', o que significa que ele só vai corresponder ao mesmo texto que estava no primeiro grupo (o grupo
([A-Z][A-Z0-9]*)`) (neste caso, ele está correspondendo à etiqueta final).