matchPath = (path, url) => {
  // Remove possible query fragments, which are not supported by iOS and some
  // versions of Anroid.
  const [urlCleaned] = url.split('?');

  // Append trailing slash for compatibility with pathToRegexp
  const urlToMatch = !urlCleaned.endsWith('/') ? `${urlCleaned}/` : urlCleaned;

  // Return the regex and the keys that can be parsed from a uri path.
  const { re, keys } = compilePathToRegex(path);

  // Check if the given url matches the uri path.
  const match = re.exec(urlToMatch);

  // If there is no match, then return null.
  if (!match) {
    return null;
  }

  // Destructure to return the compiled url (aka the reconstructed url based
  // on the regex and the url parameters.
  const [compiledUrl, ...values] = match;

  // If there is an inexact match (aka the compiled path does not match the
  // given url, then return null)
  if (urlToMatch !== compiledUrl) {
    return null;
  }

  const params = keys.reduce((acc, key, index) => Object.assign({}, acc, { [key.name]: values[index] }), {});

  return { path, params };
}
This function accepts a uri path and an actual url. It determines whether
or not they match one another. If they do not match, the funtion returns null.
If they do match, then the function returns the path and the params parsed
from the url.

@param {String} path - a uri path in standard template (https://tools.ietf.org/html/rfc6570)
@param {String} url - a url that may or may not match the given path

Case 1 - path Does Not Match Url:
  Sample Input: (path: "/edit/organization/(:id)", url: "/user/300002/")

  Sample Output: null

Case 2 - path Does Match Url:
  Sample Input: (path: "/user/:id/", url: "/user/300002/")

  Sample Output:
  {
      path: "/user/:id/",
      params: {
          id: "300002",
      }
  }