Come si usano i gruppi non catturanti, cioè (?:)
, nelle espressioni regolari e a cosa servono?
?:
si usa quando si vuole raggruppare un'espressione, ma non si vuole salvarla come porzione di stringa abbinata/catturata.
Un esempio potrebbe essere qualcosa che corrisponde a un indirizzo IP:
/(?:\d{1,3}\.){3}\d{1,3}/
Si noti che non mi interessa salvare i primi 3 ottetti, ma il raggruppamento (?:...)
mi permette di abbreviare la regex senza incorrere nell'overhead di catturare e memorizzare una corrispondenza.
Rende il gruppo non catturante, il che significa che la sottostringa abbinata a quel gruppo non sarà inclusa nell'elenco delle catture. Un esempio in rubino per illustrare la differenza:
"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]
I gruppi che catturano si possono usare in seguito nella regex per corrispondere oppure si possono usare nella parte di sostituzione della regex. Fare un gruppo non-catturante semplicemente esenta quel gruppo dall'essere usato per uno di questi motivi.
I gruppi non catturanti sono ottimi se state cercando di catturare molte cose diverse e ci sono alcuni gruppi che non volete catturare.
Questa è più o meno la ragione per cui esistono. Mentre stai imparando sui gruppi, impara a conoscere i Gruppi atomici, fanno molto! Ci sono anche i gruppi lookaround, ma sono un po' più complessi e non vengono usati molto.
Esempio di utilizzo più avanti nella regex (backreference):
<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>
[ Trova un tag xml (senza supporto ns) ]
([A-Z][A-Z0-9]*)
è un gruppo di cattura (in questo caso è il tagname)
Più avanti nella regex c'è \1
che significa che corrisponderà solo allo stesso testo che era nel primo gruppo (il gruppo ([A-Z][A-Z0-9]*)
) (in questo caso corrisponde al tag finale).