The Dark Corners of Regex: Passive Groups

If you’re a regex nerd like I am, you probably take pride in knowing all sorts of neat syntax to add to your patterns. My current favorite is the negative lookbehind, because like I said, I really am that big a nerd.

Even with my longstanding love of regex, however, I was unaware of a tiny but handy little bit of functionality called “passive groups”. It’s just like a regular group, but it doesn’t create a backreference (ie. it’s effectively discarded once the match is made).

An Example of Passive Groups

A pattern with a regular group (([^“\’;]+)), which creates a backreference for later use:

import ["\']?([^"\';]+)["\']?;

That pattern will match import statements in CSS, but it won’t match an “old style” import statement:

import ”style.css“; /* will be matched */
import url('style.css'); /* will not be matched */

So we need to optionally match the “url()” bit, but we really don’t need that little bit to create a backreference. In comes the passive groups:

import (?:url\()?[”\’]?([^“\’;]+)[”\’]? (?:\))?;

Notice the passive group is (?:match), versus (match). A nice benefit is that you can modify your patterns without needing to change any code that uses the backreferences.

I wouldn’t blog about it if Google had any idea what it was, but somehow there’s almost nothing (seriously) about “passive groups” in a Google search.