Skip to content

Commit

Permalink
Merge pull request #3217 from taion/speed-up-pattern-match
Browse files Browse the repository at this point in the history
Speed up pattern matching
  • Loading branch information
mjackson committed Mar 22, 2016
2 parents 90ceb42 + 54007fd commit 8e9869f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 33 deletions.
53 changes: 21 additions & 32 deletions modules/PatternUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ function _compilePattern(pattern) {
}

if (match[1]) {
regexpSource += '([^/?#]+)'
regexpSource += '([^/]+)'
paramNames.push(match[1])
} else if (match[0] === '**') {
regexpSource += '([\\s\\S]*)'
regexpSource += '(.*)'
paramNames.push('splat')
} else if (match[0] === '*') {
regexpSource += '([\\s\\S]*?)'
regexpSource += '(.*?)'
paramNames.push('splat')
} else if (match[0] === '(') {
regexpSource += '(?:'
Expand Down Expand Up @@ -95,43 +95,32 @@ export function matchPattern(pattern, pathname) {
regexpSource += '/*' // Capture path separators

// Special-case patterns like '*' for catch-all routes.
const captureRemaining = tokens[tokens.length - 1] !== '*'

if (captureRemaining) {
// This will match newlines in the remaining path.
regexpSource += '([\\s\\S]*?)'
if (tokens[tokens.length - 1] === '*') {
regexpSource += '$'
}

const match = pathname.match(new RegExp('^' + regexpSource + '$', 'i'))
const match = pathname.match(new RegExp(`^${regexpSource}`, 'i'))

let remainingPathname, paramValues
if (match != null) {
if (captureRemaining) {
remainingPathname = match.pop()
const matchedPath =
match[0].substr(0, match[0].length - remainingPathname.length)

// If we didn't match the entire pathname, then make sure that the match
// we did get ends at a path separator (potentially the one we added
// above at the beginning of the path, if the actual match was empty).
if (
remainingPathname &&
matchedPath.charAt(matchedPath.length - 1) !== '/'
) {
return {
remainingPathname: null,
paramNames,
paramValues: null
}
const matchedPath = match[0]
remainingPathname = pathname.substr(matchedPath.length)

// If we didn't match the entire pathname, then make sure that the match we
// did get ends at a path separator (potentially the one we added above at
// the beginning of the path, if the actual match was empty).
if (
remainingPathname &&
matchedPath.charAt(matchedPath.length - 1) !== '/'
) {
return {
remainingPathname: null,
paramNames,
paramValues: null
}
} else {
// If this matched at all, then the match was the entire pathname.
remainingPathname = ''
}

paramValues = match.slice(1).map(
v => v != null ? decodeURIComponent(v) : v
)
paramValues = match.slice(1).map(v => v && decodeURIComponent(v))
} else {
remainingPathname = paramValues = null
}
Expand Down
2 changes: 1 addition & 1 deletion modules/__tests__/getParams-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ describe('getParams', function () {
expect(getParams('/files/*', '/files/my/photo.jpg')).toEqual({ splat: 'my/photo.jpg' })
expect(getParams('/files/*', '/files/my/photo.jpg.zip')).toEqual({ splat: 'my/photo.jpg.zip' })
expect(getParams('/files/*.jpg', '/files/my/photo.jpg')).toEqual({ splat: 'my/photo' })
expect(getParams('/files/*.jpg', '/files/my/new\nline.jpg')).toEqual({ splat: 'my/new\nline' })
expect(getParams('/files/*.jpg', '/files/my/new%0Aline.jpg')).toEqual({ splat: 'my/new\nline' })
})
})

Expand Down

0 comments on commit 8e9869f

Please sign in to comment.