Skip to content

Instantly share code, notes, and snippets.

@herdianf
Created December 3, 2023 03:22
Show Gist options
  • Save herdianf/0da942462eb4357b982d3cd19ed0778c to your computer and use it in GitHub Desktop.
Save herdianf/0da942462eb4357b982d3cd19ed0778c to your computer and use it in GitHub Desktop.
Simple express router pattern matching
/**
* Match request path with route style path.
*
* @param {string} reqpath The request path
* @param {string} routepath The route pattern path
* @return {Object|boolean} matches object if match or false if not match
*
*/
function match(reqpath, routepath) {
if (reqpath === routepath) return {}
let segments = reqpath.split('/').filter(Boolean);
let route = routepath.split('/').filter(Boolean);
let max = Math.max(segments.length, route.length);
let matches = {}
let ret;
for (let i = 0; i < max; i++) {
if (route[i] && route[i].charAt(0) === ':') {
let param = route[i].replace(/(^:|[+*?]+$)/g, ''),
flags = (route[i].match(/[+*?]+$/) || {})[0] || '',
plus = ~flags.indexOf('+'),
star = ~flags.indexOf('*'),
val = segments[i] || '';
if (!val && !star && (flags.indexOf('?') < 0 || plus)) {
ret = false;
break;
}
matches[param] = decodeURIComponent(val);
if (plus || star) {
matches[param] = segments.slice(i).map(decodeURIComponent).join('/');
break;
}
} else if (route[i] !== segments[i]) {
ret = false;
break;
}
}
return ret === false ? false : matches
}
// Example usage
const routes = [
{
path: '/',
name: 'index',
},
{
path: '/pages',
name: 'pageList',
},
{
path: '/page/:pagename',
name: 'pageDetail',
}
];
let path = '/page/some-page-name';
for(let i = 0; i < routes.length; i++) {
let match = match(path, routes[i].path)
if (match) {
console.log(match, routes[i].name)
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment