Iterating Strings with Regex in JavaScript

Demonstrating matchAll by reformatting Markdown with named capture groups

Why is iteration with Regex important — and useful?

Introduction to Iteration with matchAll

const matches = myString.matchAll(regex);for (const match of matches) {
...
}

How a Match is Structured

// a regular expression testing two capture groupsconst regexp = /match \[(.*?)\]\[(.*?)\]/ig;const myString = "Testing a match [group 1] [group 2]";
const matchAll = myString.matchAll(regexp);for (const match of matches) {

// the complete match
const fullMatch = match[0];

// isolating each capture group match
const group1 = match[1];
const group2 = match[2];
// index of where the match starts
const cursorPos = match.index;
}
console.log(match[0]);
> match [group 1] [group 2]
console.log(match[1]);
> group 1
console.log(match[2]);
> group 2
console.log(cursorPos);
> 10
const matchEndPos = cursorPos + match[0].length;

Advantages of the iterator

Named Capture Groups within `match`

const myString = "Testing a match [group 1] [group 2]";const regexp = /match \[(?<mygroup>.*?)\]\[(?<anothergroup>.*?)\]/ig;
for (const match of matches) {

// accessing groups via destructuring `match`
const { groups: { mygroup, anothergroup }, index } = match;
console.log(mygroup);
> group 1
console.log(anothergroup);
> group 2
}

Matching Markdown Rules with matchAll

Combining markdown rules with |

// either match bold, italic or link formatted markdownconst regex = /(__(?<bold>.*?)__)|(_(?<italic>.*?)_)|(?<link>\[(?<text>[\w\s\d]+)\]\((?<url>https?:\/\/([a-z0-9@#/.-]+))\))/ig
// bold text - __text__
(__(?<bold>.*?)__)
|// italic text - _text_
(_(?<italic>.*?)_)
|// link - [link text](url...)
(?<link>\[(?<text>[\w\s\d]+)\]\((?<url>https?:\/\/([a-z0-9@#/.-]+))\))
// matching a string with three Markdown rulesconst str = "Testing some __bold text__ and _italic text_ with my Medium link: [Here](https://medium.com/@rossbulat)";let matches = str.matchAll(regex);for (let match of matches) {
console.log(match.groups);
}
// `match.groups` of a matched Markdown linkconsole.log(match.groups);>
{
bold: undefined,
italic: undefined,
link: "[Here](https://medium.com/@rossbulat)",
text: "Here",
url: "https://medium.com/@rossbulat"}
}

Reformatting Markdown into HTML

// destructuring `match.groups`const { groups: { bold, italic, link, text, url }, index } = match;
// append string content from the last matchreformattedStr += myStr.substr(cursorPos, (index - cursorPos));
// test each rule and append to reformatted stringif (bold !== undefined) {
reformattedStr += '<b>' + bold + '</b>';
}
else if (italic !== undefined) {
reformattedStr += '<i>' + italic + '</i>';
}
else if (link !== undefined) {
reformattedStr += '<a href="' + url + '">' + text + '</a>';
}
// appending content after last matchif (cursorPos < myStr.length) {
reformattedStr += myStr.substr(cursorPos, (myStr.length - cursorPos));
}

In Summary

Programmer and Author. Director @ JKRBInvestments.com. Creator of LearnChineseGrammar.com for iOS.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store