Skip to main content
Ben Nadel at CFCamp 2023 (Freising, Germany) with: Roman Schick
Ben Nadel at CFCamp 2023 (Freising, Germany) with: Roman Schick

Different Browsers Use Different Non-Matching Captured RegEx Pattern Values

By
Published in Comments (2)

Yesterday, Alec Perkins brought it to my attention that Chrome was passing in an undefined value for a non-matching, captured group in a regular expression (RegEx) replace function. This is a different behavior than Firefox, which passes in an empty string for non-matching, captured groups. I typically only test my Javascript in Firefox (yes, it's a bad habit); so, after hearing this, I wanted to test this feature in a few different browsers to see how they all behaved. The demo for the experiment is quite simple - I'm just matching a pattern than has an optional, but non-matched group:

<!DOCTYPE HTML>
<html>
<head>
	<title>Javascript String Replace Data Types</title>
	<script type="text/javascript">

		// Create a string to test.
		var test = "You are just too sexy!";

		// Create a pattern to match a sub-string with an optional
		// capturing group - "way" is not required.
		var pattern = new RegExp( "((way )?too sexy)", "gi" );

		// Loop over the matches, passing each set of captured groups
		// to the given function. In this case, the second captured
		// group will be the OPTIONAL part of the pattern.
		test.replace(
			pattern,
			function( $0, $1, $2 ){

				// Alert the TYPE of data type passed-in for the non-
				// captured group value.
				alert( typeof( $2 ) );

				// Alert the boolean-cast of the group.
				alert( !!$2 );

			}
		);

	</script>
</head>
<body>
	<!--- Left intentially blank. --->
</body>
</html>

Here, I am looking for the regular expression pattern:

"((way )?too sexy)"

In this pattern, the substring, "way ", is an optional, captured group and will, in fact, not be matched in our test string, "You are just too sexy!". In this scenario, we can then see how the different browsers pass in the second captured (but not matched) group.

I tested this in Firefox, Chrome, IE, and Safari and here is what we get:

Firefox:
string
false

Chrome:
undefined
false

Safari:
undefined
false

IE:
undefined
false

As it turns out, Firefox is the odd man out here, being the only browser that passes in an empty string for non-matching groups. All of the other browsers pass in "undefined" / null data types for non-matching groups. While this difference is strange, the upside is that both empty strings and undefined values are "falsey" values in Javascript and can be implicitly cast to False for control flow decisions. I know some people frown upon the use of truthy / falsey values as Conditions, but when different browsers pass in different falsey data types, this feature really helps us to simplify our control flow logic.

Note to self: be sure to test Javascript in at least two browsers!

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel