Tech Note: Taming Javascript Regular Expressions

De-uglification
LGF • Views: 24,169

Yesterday I worked out a nice way to make long Javascript regular expressions much easier to build, maintain and update, so here’s one of those tech notes that will quickly become an open thread. (Somebody might find this useful, though.)

The purpose of the following code is to make sure that all outgoing links at LGF open in a new window, but what makes it a bit tricky is that I want some internal LGF links to open in a new window as well. Handling this in Javascript instead of manually adding the attribute target="_blank" to the link’s HTML code is much more elegant, and used to be necessary to produce valid code in some types of HTML. (The attribute’s now perfectly valid in HTML 5.)

Here’s the first draft of this Javascript code; it uses jQuery’s .on() function to watch for all clicks on links, then passes the href of the link (the destination URL) through a series of regular expressions to decide whether or not to add target="_blank" to the tag. And boy, is it ever messy.

$('body').on('click', 'a', function() {
	var that = $(this),
		href = that.attr('href');
	if (href.match(/^http:\/\/littlegreenfootballs\.com\/article\/|^http:\/\/littlegreenfootballs\.com\/page\/|^\/article\/|^\/page\/|^http:\/\/littlegreenfootballs\.com\/day\/|^http:\/\/littlegreenfootballs\.com\/pages|^\/$/i) === false || href.match(/lgf-media-library\.php|lgf-image-library\.php|lgf-pages-dashboard\.php|^https?:\/\/(?!littlegreenfootballs\.com).*/i)) {
		that.attr('target', '_blank');
	}
	return true;
});

OK, that incredibly long string of cryptic spaghetti gets the job done, but it’s fugly, difficult to update, and invites typos. The code works, yet it is heinous.

The problem is that regular expression literals in Javascript can’t be broken apart into separate lines to make their purpose clearer, because they’re not actually strings — they’re a special Javascript type that has to be defined on one line.

However, by defining the regular expressions as instances of Javascript’s built-in RegExp object, we can define them as strings, and write some code that’s much cleaner and easier to work with:

$('body').on('click', 'a', function() {
	var that = $(this),
		href = that.attr('href'),
		same = RegExp([
			'^http:\/\/littlegreenfootballs\.com\/article\/',
			'^http:\/\/littlegreenfootballs\.com\/page\/',
			'^\/article\/',
			'^\/page\/',
			'^http:\/\/littlegreenfootballs\.com\/day\/',
			'^http:\/\/littlegreenfootballs\.com\/pages',
			'^\/$'
		].join('|'), 'i'),
		open = RegExp([
			'lgf-media-library\.php',
			'lgf-image-library\.php',
			'lgf-pages-dashboard\.php',
			'^https?:\/\/(?!littlegreenfootballs\.com).*'
		].join('|'), 'i');
	if (href.match(same) === false || href.match(open)) {
		that.attr('target', '_blank');
	}
	return true;
});

The regular expressions are assigned to the variables same (for URLs that must open in the same window) and open (for URLs that open in a new window). The actual strings that will become our regular expressions are elements in an array (inside the square brackets) that are concatenated together into a long string with the join function, inserting the | character (which means ‘or’ in a regex) between each element.

Now, if I need to update either list it’s a simple matter of adding another array element to those definitions in lines 4 through 18, and I can see at a glance exactly which URLs are being filtered for which purpose.

I know, I haven’t explained exactly how those regular expressions really work — I will leave that as an exercise for you, dear reader, should you be so inclined. The only one that’s tricky at all is on line 17; it uses a negative look-ahead to match all http or https links that are not on the domain littlegreenfootballs.com.

(I’ve simplified this a bit for purposes of illustration. In the actual deployed LGF code, the regular expressions are defined once at page load and stored in a global name-spaced object, so they don’t have to be created on every click of a link. But I didn’t want to get into all that … this time.)

Jump to top

Create a PageThis is the LGF Pages posting bookmarklet. To use it, drag this button to your browser's bookmark bar, and title it 'LGF Pages' (or whatever you like). Then browse to a site you want to post, select some text on the page to use for a quote, click the bookmarklet, and the Pages posting window will appear with the title, text, and any embedded video or audio files already filled in, ready to go.
Or... you can just click this button to open the Pages posting window right away.
Last updated: 2023-04-04 11:11 am PDT
LGF User's Guide RSS Feeds

Help support Little Green Footballs!

Subscribe now for ad-free access!Register and sign in to a free LGF account before subscribing, and your ad-free access will be automatically enabled.

Donate with
PayPal
Cash.app
Recent PagesClick to refresh
The Pandemic Cost 7 Million Lives, but Talks to Prevent a Repeat Stall In late 2021, as the world reeled from the arrival of the highly contagious omicron variant of the coronavirus, representatives of almost 200 countries met - some online, some in-person in Geneva - hoping to forestall a future worldwide ...
Cheechako
3 days ago
Views: 121 • Comments: 0 • Rating: 1
Texas County at Center of Border Fight Is Overwhelmed by Migrant Deaths EAGLE PASS, Tex. - The undertaker lighted a cigarette and held it between his latex-gloved fingers as he stood over the bloated body bag lying in the bed of his battered pickup truck. The woman had been fished out ...
Cheechako
2 weeks ago
Views: 282 • Comments: 0 • Rating: 1