Express路由param正则表达式(*)`是什么意思?

时间:2018-03-19 09:31:09

标签: node.js regex express

我在Perl身上割伤了牙齿。我对正则表达式很满意(但仍然容易出错)。

为什么(*)在名为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中可能会纠正的错误?

1 个答案:

答案 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

中找到