为什么(*)
在名为param的Express路由中作为正则表达式工作?
为什么(.*)
不能作为名为param的Express路由中的正则表达式工作?
像([\\w:./]+)
这样的方法更可靠吗?
我正在尝试使用一个意图在值中包含斜杠的路由参数。
e.g。
如果请求是:
http://www.example.com/new/https://www.youtube.com/trending
......我正在使用这条路线:
app.get('/new/:url', (req, res) => {
console.log('new')
console.log(req.params.url)
})
我希望url
等于https://www.youtube.com/trending
我知道路径是在斜线上分开的,所以我想我可以使用a regular expression in parentheses after the named parameter来匹配斜杠。
我尝试了/new/:url(.*)
,我认为应该greedily匹配任何东西,包括斜杠,但这会使路线完全失败。为什么这不起作用?
通过我自己的反复试验,我发现/new/:url([\\w:./]+)
有效。这对我来说很有意义,但似乎不必要地复杂。这是“正确的方式”吗?
最让我困惑的是我找到的in a YouTube video example ...为什么/new/:url(*)
有效? *
表示前一项中的0或更多,但星号前没有任何内容。
我有一种感觉,答案在于this GitHub issue,但我不清楚通过阅读线程到底发生了什么。 (*)
是否依赖于下一版Express中可能会纠正的错误?
答案 0 :(得分:2)
问题的第一部分由引用的GitHub issue回答。
至于.*
为什么不起作用,点(.
)在此实现中不是特殊字符。它只是一个点。
从引用的GitHub问题我明白星号(*
)根本不被理解为量词。它只匹配一切。那就是(*)
工作的原因。
GitHub问题未解释的部分是.*
,在考虑已知错误时,应该匹配单个字符,后跟其他所有字符。但是,通过反复试验,我确定.
根本不是一个特殊字符。在这个实现中,它只是一个字面点。
例如,如果请求是:
http://www.example.com/new/https://www.youtube.com/trending
......我正在使用这条路线:
app.get('/new/:url(.*)', (req, res) => {
console.log('new')
console.log(req.params.url)
})
路线不会匹配,但需要
http://www.example.com/new/.https://www.youtube.com/trending
会匹配(请注意https
前面的点),req.params.url
等于.https://www.youtube.com/trending
。
我使用以下代码进行测试:
const express = require('express')
const app = express()
const port = process.env.PORT || 3000
app.get('/dotStar/:dotStar(.*)', (request, response) => {
console.log(`test request, dotStar: ${request.params.dotStar}`)
response.send(`dotStar: ${request.params.dotStar}`)
})
app.get('/star/:star(*)', (request, response) => {
console.log(`test request, star: ${request.params.star}`)
response.send(`star: ${request.params.star}`)
})
app.get('/regexStar/:regexStar([a-z][a-z-]*)', (request, response) => {
console.log(`test request, regexStar: ${request.params.regexStar}`)
response.send(`regexStar: ${request.params.regexStar}`)
})
app.get('/dotDotPlus/:dotDotPlus(..+)', (request, response) => {
console.log(`test request, dotDotPlus: ${request.params.regexStar}`)
response.send(`dotDotPlus: ${request.params.dotDotPlus}`)
})
app.get('/regex/:regex([\\w:./-]+)', (request, response) => {
console.log(`test request, regex: ${request.params.regex}`)
response.send(`regex: ${request.params.regex}`)
})
app.listen(port, () => {
console.log(`Listening on port ${port}...`)
})
- 也可在this gist
中找到