@@ -45,181 +45,207 @@ import pathToRegexp "github.com/soongo/path-to-regexp"
45
45
- ** tokens** An array to populate with tokens found in the path.
46
46
- token
47
47
- ** Name** The name of the token (` string ` for named or ` number ` for index)
48
- - ** Prefix** The prefix character for the segment (e.g. ` / ` )
49
- - ** Delimiter** The delimiter for the segment (same as prefix or default delimiter)
50
- - ** Optional** Indicates the token is optional (` boolean ` )
51
- - ** Repeat** Indicates the token is repeated (` boolean ` )
48
+ - ** Prefix** The prefix string for the segment (e.g. ` "/" ` )
49
+ - ** Suffix** The suffix string for the segment (e.g. ` "" ` )
52
50
- ** Pattern** The RegExp used to match this token (` string ` )
51
+ - ** Modifier** The modifier character used for the segment (e.g. ` ? ` )
53
52
- ** options**
54
53
- ** Sensitive** When ` true ` the regexp will be case sensitive. (default: ` false ` )
55
54
- ** Strict** When ` true ` the regexp allows an optional trailing delimiter to match. (default: ` false ` )
56
55
- ** End** When ` true ` the regexp will match to the end of the string. (default: ` true ` )
57
56
- ** Start** When ` true ` the regexp will match from the beginning of the string. (default: ` true ` )
58
- - ** Delimiter** The default delimiter for segments. (default: ` '/' ` )
57
+ - ** Validate** When ` false ` the function can produce an invalid (unmatched) path. (default: ` true ` )
58
+ - ** Delimiter** The default delimiter for segments, e.g. ` [^/] ` for ` :named ` patterns. (default: ` '/' ` )
59
59
- ** EndsWith** Optional character, or list of characters, to treat as "end" characters.
60
- - ** Whitelist ** List of characters to consider delimiters when parsing. (default: ` nil ` , any character )
60
+ - ** prefixes ** List of characters to automatically consider prefixes when parsing. (default: ` ./ ` )
61
61
- ** Encode** How to encode uri. (default: ` func (uri string, token interface{}) string { return uri } ` )
62
62
- ** Decode** How to decode uri. (default: ` func (uri string, token interface{}) string { return uri } ` )
63
63
64
64
``` go
65
65
var tokens []pathToRegexp.Token
66
66
regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /foo/:bar" , &tokens, nil ))
67
- // regexp: ^\/foo\/([^\/]+?)(?:\/)?$
68
- // tokens: [{Name:"bar", Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:false, Pattern:"[^\\/]+?"} }]
67
+ // regexp: ^\/foo(?: \/([^\/]+?))[\/]?(?=$)
68
+ // tokens: [{Name:"bar", Prefix:"/", Suffix:" ", Pattern:"[^\\/]+?", Modifier:"" }]
69
69
```
70
70
71
71
** Please note:** The ` Regexp ` returned by ` path-to-regexp ` is intended for ordered data (e.g. pathnames, hostnames). It can not handle arbitrarily ordered data (e.g. query strings, URL fragments, JSON, etc).
72
72
73
73
### Parameters
74
74
75
- The path argument is used to define parameters and populate the list of tokens.
75
+ The path argument is used to define parameters and populate tokens.
76
76
77
77
#### Named Parameters
78
78
79
- Named parameters are defined by prefixing a colon to the parameter name (` :foo ` ). By default, the parameter will match until the next prefix (e.g. ` [^/]+ ` ).
79
+ Named parameters are defined by prefixing a colon to the parameter name (` :foo ` ).
80
80
81
81
``` go
82
- regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo/:bar" , nil , nil ))
82
+ var tokens []pathToRegexp.Token
83
+ regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo/:bar" , &tokens, nil ))
83
84
// tokens: [
84
- // {Name:"foo", Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:false, Pattern:"[^\\/]+?"},
85
- // {Name:"bar", Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:false, Pattern:"[^\\/]+?"}
85
+ // {Name:"foo", Prefix:"/", Suffix:" ", Pattern:"[^\\/]+?", Modifier:" "},
86
+ // {Name:"bar", Prefix:"/", Suffix:" ", Pattern:"[^\\/]+?", Modifier:" "}
86
87
// ]
87
88
88
- match , err := regexp.FindStringMatch (" /test/route" )
89
+ match , _ := regexp.FindStringMatch (" /test/route" )
89
90
for _ , g := range match.Groups () {
90
91
fmt.Printf (" %q " , g.String ())
91
92
}
92
- fmt.Printf (" %d , %q \n " , match.Index , match)
93
- // => "/test/route" "test" "route" 0, "/test/route"
93
+ fmt.Printf (" %d %q \n " , match.Index , match)
94
+ // => "/test/route" "test" "route" 0 "/test/route"
94
95
```
95
96
96
97
** Please note:** Parameter names must use "word characters" (` [A-Za-z0-9_] ` ).
97
98
98
- #### Parameter Modifiers
99
+ ##### Custom Matching Parameters
99
100
100
- ##### Optional
101
-
102
- Parameters can be suffixed with a question mark (` ? ` ) to make the parameter optional.
101
+ Parameters can have a custom regexp, which overrides the default match (` [^/]+ ` ). For example, you can match digits or names in a path:
103
102
104
103
``` go
105
- regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo/:bar?" , nil , nil ))
106
- // tokens: [
107
- // {Name:"foo", Prefix:"/", Delimiter:"/", Optional:false, Repeat:false, Pattern:"[^\\/]+?"},
108
- // {Name:"bar", Prefix:"/", Delimiter:"/", Optional:true, Repeat:false, Pattern:"[^\\/]+?"}
109
- // ]
104
+ var tokens []pathToRegexp.Token
105
+ regexpNumbers := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /icon-:foo(\\ d+).png" , &tokens, nil ))
106
+ // tokens: [{Name:"foo", Prefix:"", Suffix:"", Pattern:"\\d+", Modifier:""}]
110
107
111
- match , err := regexp .FindStringMatch (" /test " )
108
+ match , _ := regexpNumbers .FindStringMatch (" /icon-123.png " )
112
109
for _ , g := range match.Groups () {
113
110
fmt.Printf (" %q " , g.String ())
114
111
}
115
- fmt.Printf (" %d , %q \n " , match.Index , match)
116
- // => "/test" "test" "" 0, "/test"
112
+ // => "/icon-123.png" "123"
117
113
118
- match, err = regexp.FindStringMatch (" /test/route" )
114
+ match , _ := regexpNumbers.FindStringMatch (" /icon-abc.png" )
115
+ fmt.Println (match)
116
+ // => <nil>
117
+
118
+ tokens = make ([]pathToRegexp.Token , 0 )
119
+ regexpWord := pathToRegexp (" /(user|u)" , &tokens, nil )
120
+ // tokens: [{Name:0, Prefix:"/", Suffix:"", Pattern:"user|u", Modifier:""}]
121
+
122
+ match, _ = regexpWord.FindStringMatch (" /u" )
119
123
for _ , g := range match.Groups () {
120
124
fmt.Printf (" %q " , g.String ())
121
125
}
122
- fmt.Printf (" %d , %q \n " , match.Index , match)
123
- // => "/test/route" "test" "route" 0, "/test/route"
126
+ // => "/u" "u"
127
+
128
+ match, _ = regexpWord.FindStringMatch (" users" )
129
+ fmt.Println (match)
130
+ // => <nil>
124
131
```
125
132
126
- ** Tip:** The prefix is also optional, escape the prefix ` \/ ` to make it required .
133
+ ** Tip:** Backslashes need to be escaped with another backslash in JavaScript strings .
127
134
128
- ##### Zero or more
135
+ ##### Custom Prefix and Suffix
129
136
130
- Parameters can be suffixed with an asterisk ( ` * ` ) to denote a zero or more parameter matches. The prefix is used for each match.
137
+ Parameters can be wrapped in ` {} ` to create custom prefixes or suffixes for your segment:
131
138
132
139
``` go
133
- regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo*" , nil , nil ))
134
- // tokens: [{Name:"foo", Prefix:"/", Delimiter:"/", Optional:true, Repeat:true, Pattern:"[^\\/]+?"}]
140
+ regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:attr1?{-:attr2}?{-:attr3}?" , nil , nil ))
135
141
136
- match , err := regexp.FindStringMatch (" /" )
142
+ match , _ := regexp.FindStringMatch (" /test " )
137
143
for _ , g := range match.Groups () {
138
144
fmt.Printf (" %q " , g.String ())
139
145
}
140
- fmt.Printf (" %d , %q \n " , match.Index , match)
141
- // => "/" "" 0, "/"
146
+ // => "/test" "test" "" ""
142
147
143
- match, err = regexp.FindStringMatch (" /bar/baz " )
148
+ match, _ = regexp.FindStringMatch (" /test-test " )
144
149
for _ , g := range match.Groups () {
145
150
fmt.Printf (" %q " , g.String ())
146
151
}
147
- fmt.Printf (" %d , %q \n " , match.Index , match)
148
- // => "/bar/baz" "bar/baz" 0, "/bar/baz"
152
+ // => "/test-test" "test" "test" ""
149
153
```
150
154
151
- ##### One or more
155
+ #### Unnamed Parameters
152
156
153
- Parameters can be suffixed with a plus sign ( ` + ` ) to denote a one or more parameter matches. The prefix is used for each match.
157
+ It is possible to write an unnamed parameter that only consists of a regexp. It works the same the named parameter, except it will be numerically indexed:
154
158
155
159
``` go
156
- regexp := pathToRegexp.Must (pathToRegexp. PathToRegexp ( " /:foo+ " , nil , nil ))
157
- // tokens: [{Name:"foo", Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:true, Pattern:"[^\\/]+?"}]
158
-
159
- match , err := regexp. FindStringMatch ( " / " )
160
- fmt. Println (match)
161
- // => nil
160
+ var tokens [] pathToRegexp.Token
161
+ regexp := pathToRegexp. Must (pathToRegexp. PathToRegexp ( " /:foo/(.*) " , &tokens, nil ))
162
+ // tokens: [
163
+ // {Name:"foo", Prefix:"/", Suffix:"", Pattern:"[^\\/]+?", Modifier:""}
164
+ // {Name:0, Prefix:"/", Suffix:"", Pattern:".*", Modifier:""}
165
+ // ]
162
166
163
- match, err = regexp.FindStringMatch (" /bar/baz " )
167
+ match , _ : = regexp.FindStringMatch (" /test/route " )
164
168
for _ , g := range match.Groups () {
165
169
fmt.Printf (" %q " , g.String ())
166
170
}
167
- fmt.Printf (" %d , %q \n " , match.Index , match)
168
- // => "/bar/baz " "bar/baz" 0, "/bar/baz "
171
+ fmt.Printf (" %d %q \n " , match.Index , match)
172
+ // => "/test/route " "test" "route" 0 "/test/route "
169
173
```
170
174
171
- #### Unnamed Parameters
175
+ #### Modifiers
172
176
173
- It is possible to write an unnamed parameter that only consists of a matching group. It works the same as a named parameter, except it will be numerically indexed.
177
+ Modifiers must be placed after the parameter (e.g. ` /:foo? ` , ` /(test)? ` , or ` /:foo(test)? ` ).
178
+
179
+ ##### Optional
180
+
181
+ Parameters can be suffixed with a question mark (` ? ` ) to make the parameter optional.
174
182
175
183
``` go
176
- regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo/(.*) " , nil , nil ))
184
+ regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo/:bar? " , nil , nil ))
177
185
// tokens: [
178
- // {Name:"foo", Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:false, Pattern:"[^\\/]+?"},
179
- // {Name:0 , Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:false, Pattern:".* "}
186
+ // {Name:"foo", Prefix:"/", Suffix:" ", Pattern:"[^\\/]+?", Modifier:""}
187
+ // {Name:"bar" , Prefix:"/", Suffix:" ", Pattern:"[^\\/]+?", Modifier:"? "}
180
188
// ]
181
189
182
- match , err := regexp.FindStringMatch (" /test/route" )
190
+ match , err := regexp.FindStringMatch (" /test" )
191
+ for _ , g := range match.Groups () {
192
+ fmt.Printf (" %q " , g.String ())
193
+ }
194
+ fmt.Printf (" %d %q \n " , match.Index , match)
195
+ // => "/test" "test" "" 0 "/test"
196
+
197
+ match, err = regexp.FindStringMatch (" /test/route" )
183
198
for _ , g := range match.Groups () {
184
199
fmt.Printf (" %q " , g.String ())
185
200
}
186
- fmt.Printf (" %d , %q \n " , match.Index , match)
187
- // => "/test/route" "test" "route" 0, "/test/route"
201
+ fmt.Printf (" %d %q \n " , match.Index , match)
202
+ // => "/test/route" "test" "route" 0 "/test/route"
188
203
```
189
204
190
- #### Custom Matching Parameters
205
+ ** Tip:** The prefix is also optional, escape the prefix ` \/ ` to make it required.
206
+
207
+ ##### Zero or more
191
208
192
- All parameters can have a custom regexp, which overrides the default match ( ` [^/]+ ` ). For example, you can match digits or names in a path:
209
+ Parameters can be suffixed with an asterisk ( ` * ` ) to denote a zero or more parameter matches.
193
210
194
211
``` go
195
- regexpNumbers := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /icon- :foo( \\ d+).png " , nil , nil ))
196
- // tokens: {Name:"foo", Prefix:"- ", Delimiter:"- ", Optional:false, Repeat:false, Pattern:"\\d+"}
212
+ regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo* " , nil , nil ))
213
+ // tokens: [ {Name:"foo", Prefix:"/ ", Suffix:" ", Pattern:"[^\\/]+?", Modifier:"*"}]
197
214
198
- match , err := regexpNumbers .FindStringMatch (" /icon-123.png " )
215
+ match , err := regexp .FindStringMatch (" /" )
199
216
for _ , g := range match.Groups () {
200
217
fmt.Printf (" %q " , g.String ())
201
218
}
202
- // => "/icon-123.png" "123"
203
-
204
- match, err = regexpNumbers.FindStringMatch (" /icon-abc.png" )
205
- fmt.Println (match)
206
- // => nil
219
+ fmt.Printf (" %d %q \n " , match.Index , match)
220
+ // => "/" "" 0 "/"
207
221
208
- regexpWord := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /(user|u)" , nil , nil ))
209
- // tokens: {Name:0, Prefix:"/", Delimiter:"/", Optional:false, Repeat:false, Pattern:"user|u"}
210
-
211
- match, err = regexpWord.FindStringMatch (" /u" )
222
+ match, err = regexp.FindStringMatch (" /bar/baz" )
212
223
for _ , g := range match.Groups () {
213
224
fmt.Printf (" %q " , g.String ())
214
225
}
215
- // => "/u" "u"
226
+ fmt.Printf (" %d %q \n " , match.Index , match)
227
+ // => "/bar/baz" "bar/baz" 0 "/bar/baz"
228
+ ```
216
229
217
- match, err = regexpWord.FindStringMatch (" /users" )
230
+ ##### One or more
231
+
232
+ Parameters can be suffixed with a plus sign (` + ` ) to denote a one or more parameter matches.
233
+
234
+ ``` go
235
+ regexp := pathToRegexp.Must (pathToRegexp.PathToRegexp (" /:foo+" , nil , nil ))
236
+ // tokens: [{Name:"foo", Prefix:"/", Suffix:"", Pattern:"[^\\/]+?", Modifier:"+"}]
237
+
238
+ match , err := regexp.FindStringMatch (" /" )
218
239
fmt.Println (match)
219
240
// => nil
220
- ```
221
241
222
- ** Tip:** Backslashes need to be escaped with another backslash in Go strings.
242
+ match, err = regexp.FindStringMatch (" /bar/baz" )
243
+ for _ , g := range match.Groups () {
244
+ fmt.Printf (" %q " , g.String ())
245
+ }
246
+ fmt.Printf (" %d %q \n " , match.Index , match)
247
+ // => "/bar/baz" "bar/baz" 0 "/bar/baz"
248
+ ```
223
249
224
250
### Match
225
251
@@ -250,10 +276,10 @@ fmt.Printf("%#v\n", tokens[0])
250
276
// => "/route"
251
277
252
278
fmt.Printf (" %#v \n " , tokens[1 ])
253
- // => pathToRegexp.Token{Name:"foo", Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:false, Pattern:"[^\\/]+?"}
279
+ // => pathToRegexp.Token{Name:"foo", Prefix:"/", Suffix:" ", Pattern:"[^\\/]+?", Modifier:" "}
254
280
255
281
fmt.Printf (" %#v \n " , tokens[2 ])
256
- // => pathToRegexp.Token{Name:0, Prefix:"/", Delimiter:"/ ", Optional:false, Repeat:false, Pattern:".*"}
282
+ // => pathToRegexp.Token{Name:0, Prefix:"/", Suffix:" ", Pattern:".*", Modifier:" "}
257
283
```
258
284
259
285
** Note:** This method only works with strings.
@@ -294,4 +320,4 @@ toPathRegexp = pathToRegexp.MustCompile("/user/:id(\\d+)", nil)
294
320
toPathRegexp (map [string ]string {" id" : " abc" }) // => panic
295
321
```
296
322
297
- ** Note:** The generated function will panic on invalid input. It will do all necessary checks to ensure the generated path is valid. This method only works with strings.
323
+ ** Note:** The generated function will panic on invalid input.
0 commit comments