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
*/
@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