Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Integralist
Created March 11, 2013 15:15
Show Gist options
  • Star 46 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save Integralist/5134943 to your computer and use it in GitHub Desktop.
Save Integralist/5134943 to your computer and use it in GitHub Desktop.
The difference between JavaScript's `exec` and `match` methods is subtle but important, and I always forget...
var str = "The quick brown fox jumped over the box like an ox with a sox in its mouth";
str.match(/\w(ox)/g); // ["fox", "box", "sox"]
// match (when used with a 'g' flag) returns an Array with all matches found
// if you don't use the 'g' flag then it acts the same as the 'exec' method.
str.match(/\w(ox)/); // ["fox", "ox"]
/\w(ox)/.exec(str); // ["fox", "ox"]
// the exec method returns an Array where the first index is the match and all other indexes are capturing groups
// note: adding a 'g' flag has no effect on the returned Array
/\w(ox)/g.exec(str); // ["fox", "ox"]
// although you can use a while loop with the exec method to find successive matches
var myRe = /ab*/g;
var str = "abbcdefabh";
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
var msg = "Found " + myArray[0] + ". ";
msg += "Next match starts at " + myRe.lastIndex;
console.log(msg);
}
/*
Found abb. Next match starts at 3
Found ab. Next match starts at 9
*/
@maxw3st
Copy link

maxw3st commented Mar 11, 2013

Thanks for the tip. Don't quite understand the comment about "capturing groups", but I'll look it up. Looks like that means it's returning an array of two elements consisting of the first instance of a match plus a copy of the regex string to be matched (the exec method or non-flagged match method).

@Integralist
Copy link
Author

@maxw3st capturing groups are the () in a regular expression.

If you write a regex like /\w(ox)/you're saying find a single alphanumerical character followed by the character o and then x but keep a note of the ox (i.e. capture those characters).

Capturing a group of characters can be useful for all sorts of things. I use it in my DOM Builder script to store the ID id = /#([^.]+)/.exec(tag)

@captDaylight
Copy link

Thanks for this @Integralist, I reworked this to use exec to loop through all the headers in markdown so I could get the header strings. Doing this in a functional way:

var re = /(#+)(.*)/;
var str = '## About Bottler\n\nThis is something about the project\n\n# something else\n';

function findAll(regex, sourceString, aggregator = []) {
  const arr = re.exec(sourceString);
  
  if (arr === null) return aggregator;
  
  const newString = sourceString.slice(arr.index + arr[0].length);
  return findAll(regex, newString, aggregator.concat([arr]));
}

findAll(re, str);
// [ ["## About Bottler", "##", " About Bottler"], ["# something else", "#", " something else"] ]

This is useful in my situation so I can parse out the headers AND which header type.

@panoply
Copy link

panoply commented Nov 17, 2019

@captDaylight Love the functional approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment