code: function pathToRegexp (path, keys, options) {
    keys = keys || [];
  
    if (!isArray(keys)) {
      options = keys;
      keys = [];
    } else if (!options) {
      options = {};
    }
  
    if (path instanceof RegExp) {
      return regexpToRegexp(path, keys, options);
    }
  
    if (isArray(path)) {
      return arrayToRegexp(path, keys, options);
    }
  
    var strict = options.strict;
    var end = options.end !== false;
    var route = replacePath(path, keys);
    var endsWithSlash = path.charAt(path.length - 1) === '/';
  
    // In non-strict mode we allow a slash at the end of match. If the path to
    // match already ends with a slash, we remove it for consistency. The slash
    // is valid at the end of a path match, not in the middle. This is important
    // in non-ending mode, where "/test/" shouldn't match "/test//route".
    if (!strict) {
      route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?';
    }
  
    if (end) {
      route += '$';
    } else {
      // In non-ending mode, we need the capturing groups to match as much as
      // possible by using a positive lookahead to the end or next path segment.
      route += strict && endsWithSlash ? '' : '(?=\\/|$)';
    }
  
    return attachKeys(new RegExp('^' + route, flags(options)), keys);
  }
docs: Normalize the given path string, returning a regular expression.
  
  An empty array can be passed in for the keys, which will hold the
  placeholder key descriptions. For example, using `/user/:id`, `keys` will
  contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
  
  @param  {(String|RegExp|Array)} path
  @param  {Array}                 [keys]
  @param  {Object}                [options]
  @return {RegExp}