Created
December 11, 2017 21:36
-
-
Save nadrane/eca5de5ed52c3c0d2632626fcfc6a163 to your computer and use it in GitHub Desktop.
A very simple regular expression engine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//A walkthrough of this solution exists here: https://nickdrane.com/build-your-own-regex/ | |
function matchOne(pattern, text) { | |
if (!pattern) return true; | |
if (!text) return false; | |
return pattern === "." || text === pattern; | |
} | |
function search(pattern, text) { | |
if (pattern[0] === "^") { | |
return match(pattern.slice(1), text); | |
} else { | |
return match(".*" + pattern, text); | |
} | |
} | |
function match(pattern, text) { | |
if (!pattern) return true; | |
else if (!text && pattern === "$") return true; | |
else if (pattern[1] === "?") { | |
return matchQuestion(pattern, text); | |
} else if (pattern[1] === "*") { | |
return matchStar(pattern, text); | |
} else if (pattern[0] === "(") { | |
return matchGroup(pattern, text); | |
} else { | |
return matchOne(pattern[0], text[0]) && match(pattern.slice(1), text.slice(1)); | |
} | |
} | |
function matchQuestion(pattern, text) { | |
return ( | |
(matchOne(pattern[0], text[0]) && match(pattern.slice(2), text.slice(1))) || | |
match(pattern.slice(2), text) | |
); | |
} | |
function matchStar(pattern, text) { | |
return ( | |
(matchOne(pattern[0], text[0]) && match(pattern, text.slice(1))) || | |
match(pattern.slice(2), text) | |
); | |
} | |
// Does not support nested groups | |
function matchGroup(pattern, text) { | |
const groupEnd = pattern.indexOf(")"); | |
const groupPattern = pattern.slice(1, groupEnd); | |
if (pattern[groupEnd + 1] === "?") { | |
const remainderPattern = pattern.slice(groupEnd + 2); // +2 needed to slice off the ')?' | |
return ( | |
(match(groupPattern, text.slice(0, groupPattern.length)) && | |
match(remainderPattern, text.slice(groupPattern.length))) || | |
match(remainderPattern, text) | |
); | |
} else if (pattern[groupEnd + 1] === "*") { | |
const remainderPattern = pattern.slice(groupEnd + 2); // +2 needed to slice off the ')*' | |
return ( | |
(match(groupPattern, text.slice(0, groupPattern.length)) && | |
match(pattern, text.slice(groupPattern.length))) || | |
match(remainderPattern, text) | |
); | |
} else { | |
const remainderPattern = pattern.slice(groupEnd + 1); // +1 needed to slice off the ')' | |
return ( | |
match(groupPattern, text.slice(0, groupPattern.length)) && | |
match(remainderPattern, text.slice(groupPattern.length)) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment