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

Vin*_*nce 5 regex node.js express

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

为什么(*)在名为 param 的 Express 路由中用作正则表达式?

为什么(.*)在名为 param 的 Express 路由中不能用作正则表达式?

是像([\\w:./]+)一个更可靠的方式做到这一点?


我正在尝试使用旨在在值中包含斜杠的路由参数。

例如

如果请求是:

http://www.example.com/new/https://www.youtube.com/trending
Run Code Online (Sandbox Code Playgroud)

...我正在使用这条路线:

app.get('/new/:url', (req, res) => {
  console.log('new')
  console.log(req.params.url)
})
Run Code Online (Sandbox Code Playgroud)

我要url平等https://www.youtube.com/trending

我知道路径在斜杠上分开,所以我想我可以在命名参数后的括号中使用正则表达式来匹配斜杠。

我试过/new/:url(.*),我认为它应该贪婪地匹配任何东西,包括斜线,但这使路线完全失败。为什么这不起作用?

通过我自己的反复试验,我发现这是/new/:url([\\w:./]+)有效的。这对我来说很有意义,但似乎不必要地复杂。这是“正确的方法”吗?

最让我困惑的是我在 YouTube 视频示例中找到的一个......为什么/new/:url(*)有效?该*说0或多个之前的项目,但没有什么星号之前。

我有一种感觉,答案就在这个 GitHub 问题中,但通过阅读线程我不清楚到底发生了什么。是否(*)依赖可能在下一版 Express 中更正的错误?

Vin*_*nce 6

问题的第一部分由引用的GitHub 问题回答。

至于为什么.*不起作用,点 ( .) 在此实现中不是特殊字符。这只是一个点。

从引用的 GitHub 问题中,我了解到星号 ( *) 根本不被理解为量词。它只是匹配一切。所以,这就是(*)工作的原因。

GitHub 问题未解释的部分是.*,在考虑已知错误时,应匹配单个字符后跟其他所有字符。但是,通过反复试验,我确定.根本不是特殊字符。在这个实现中,它只是一个文字点。

例如,如果请求是:

http://www.example.com/new/https://www.youtube.com/trending
Run Code Online (Sandbox Code Playgroud)

...我正在使用这条路线:

app.get('/new/:url(.*)', (req, res) => {
  console.log('new')
  console.log(req.params.url)
})
Run Code Online (Sandbox Code Playgroud)

路由不会匹配,但请求

http://www.example.com/new/.https://www.youtube.com/trending
Run Code Online (Sandbox Code Playgroud)

将匹配(注意前面的点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}...`)
})
Run Code Online (Sandbox Code Playgroud)

- 也可以在这个要点中找到