Skip to content

Commit f0aa03a

Browse files
committed
handle all matching group indexes
1 parent 2df21a1 commit f0aa03a

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

index.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ function pathtoRegexp(path, keys, options) {
2525
var strict = options.strict;
2626
var end = options.end !== false;
2727
var flags = options.sensitive ? '' : 'i';
28-
var index = 0;
2928
var extraOffset = 0;
29+
3030
keys = keys || [];
3131

3232
if (path instanceof RegExp) {
@@ -56,7 +56,7 @@ function pathtoRegexp(path, keys, options) {
5656
keys.push({
5757
name: key,
5858
optional: !!optional,
59-
index: index++,
59+
index: 0,
6060
_offset: offset + extraOffset
6161
});
6262

@@ -67,19 +67,33 @@ function pathtoRegexp(path, keys, options) {
6767
+ (star ? '((?:[\\/' + format + '].+?)?)' : '')
6868
+ ')'
6969
+ optional;
70+
7071
extraOffset += result.length - match.length;
7172

7273
return result;
7374
})
74-
.replace(/\*/g, function(star, index) {
75-
keys.forEach(function(key) {
76-
if (index < key._offset) {
77-
key.index++;
78-
}
79-
});
75+
.replace(/\*/g, function (star, index) {
76+
var len = keys.length
77+
78+
while (len-- && keys[len]._offset > index) {
79+
keys[len]._offset += 3;
80+
}
81+
8082
return '(.*)';
8183
});
8284

85+
// This is a workaround for handling *all* matching group positioning.
86+
var re = /\((?!\?)/g;
87+
var m;
88+
89+
while (m = re.exec(path)) {
90+
var len = keys.length;
91+
92+
while (len-- && keys[len]._offset > m.index) {
93+
keys[len].index++;
94+
}
95+
}
96+
8397
// If the path is non-ending, match until the end or a slash.
8498
path += (end ? '$' : (path[path.length - 1] === '/' ? '' : '(?=\\/|$)'));
8599

test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,34 @@ describe('path-to-regexp', function () {
128128
assert.equal(params[2].name, 'bar');
129129
assert.equal(params[2].index, 5);
130130

131+
assert.equal(m.length, 8);
132+
assert.equal(m[0], '/a/b/c/d/e/f/g');
133+
assert.equal(m[1], '/a');
134+
assert.equal(m[2], 'b');
135+
assert.equal(m[3], 'c');
136+
assert.equal(m[4], 'd');
137+
assert.equal(m[5], 'e');
138+
assert.equal(m[6], 'f');
139+
assert.equal(m[7], 'g');
140+
});
141+
142+
it('should have proper indexes with matching groups', function () {
143+
var params = [];
144+
var m = pathToRegExp('/:foo((\\d)+)/:bar', params).exec('/123/abc');
145+
146+
assert.equal(params.length, 2);
147+
assert.equal(params[0].name, 'foo');
148+
assert.equal(params[0].optional, false);
149+
assert.equal(params[0].index, 0);
150+
assert.equal(params[1].name, 'bar');
151+
assert.equal(params[1].optional, false);
152+
assert.equal(params[1].index, 2);
153+
154+
assert.equal(m.length, 4);
155+
assert.equal(m[0], '/123/abc');
156+
assert.equal(m[1], '3');
157+
assert.equal(m[2], '3');
158+
assert.equal(m[3], 'abc');
131159
});
132160

133161
it('should do strict matches with trailing slashes', function () {

0 commit comments

Comments
 (0)