Golang正则表达式如何实现匹配第一组时忽略第二组?

Golang正则表达式如何实现匹配第一组时忽略第二组? 我有一个这样的正则表达式:

isValidPath = regexp.MustCompile(`/user/action/?(.*)`)

它能匹配我感兴趣的以下两个字符串:

"/user/action" and "/user/action/someResource"

但它也会匹配另一个字符串:

"/user/actionblablablabla"

我该如何修改 isValidPath 使其不匹配最后一个字符串?它应该只匹配以下两种路径:

"/user/action" and "/user/action/someResource"

其中 someResource 可以是任何内容。


更多关于Golang正则表达式如何实现匹配第一组时忽略第二组?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

这是可行的:

isValidPath = regexp.MustCompile(`/user/action$|/user/action/(.*)`)

更多关于Golang正则表达式如何实现匹配第一组时忽略第二组?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用 /user/action(/(.*))? 并利用匹配组 2 而非组 1 来提取资源。

如果不需要匹配 /user/action/,可以将内部组改为使用 .+

不过,我认为使用正则表达式来验证这一点并不是一个好主意。相反,你可能希望使用 filepath.Match,因为这种方法通常也能确保路径的有效性。

你当前的正则表达式(以及我的建议)会允许 someRessource/someSubRessource,这可能是你想要的,也可能不是。借助上述函数和通配符,你可以使其更加明确。当然,你也可以用正则表达式实现,但这会使正则表达式变得越来越复杂。

最后但同样重要的是,我可能会使用两个独立的检查,而不是一个组合检查,来分别判断是否等于基础路径以及是否是某个资源路径。

someResource 可以是任何内容,我想要的只是一个真或假的结果。按照你的提议,我必须先提取路径然后重新验证,这不是我想要的。我只想知道路径是否符合那个标准,然后将控制权交给另一个包来处理剩下的事情。我只需要一个正则表达式来处理一个特定情况,而不是像路由器那样验证成千上万的路径,所以:

package main

import (
	"fmt"
	"regexp"
)

var rNum = regexp.MustCompile(`/user/action/(.*)|/user/action$`)

func main() {
	group := []string{
		"/user/action/",
		"/user/action/someresource/cat.png",
		"/user/action",
		"/user/actionblabla",
	}
	for _, urlPath := range group {
		fmt.Println(fmt.Sprintf("%s -> %t", urlPath, rNum.MatchString(urlPath)))
	}
}

使用我的正则表达式: var rNum = regexp.MustCompile(/user/action/(.*)|/user/action$)

输出:

/user/action/ -> true
/user/action/someresource/cat.png -> true
/user/action -> true
/user/actionblabla -> false

目前这就是我的解决方案。

你可以通过添加一个单词边界 \b 来确保 action 是一个完整的单词,或者使用更精确的路径分隔符匹配。以下是修改后的正则表达式:

isValidPath = regexp.MustCompile(`^/user/action(?:/(.*))?$`)

这个正则表达式的解释:

  • ^ 匹配字符串开始
  • /user/action 精确匹配路径
  • (?:/(.*))? 非捕获分组,匹配可选的 / 后跟任意内容
  • $ 匹配字符串结束

测试示例:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    isValidPath := regexp.MustCompile(`^/user/action(?:/(.*))?$`)
    
    tests := []string{
        "/user/action",
        "/user/action/someResource",
        "/user/actionblablablabla",
        "/user/action/",
        "/user/action/resource/subresource",
    }
    
    for _, test := range tests {
        matches := isValidPath.FindStringSubmatch(test)
        if matches != nil {
            fmt.Printf("匹配成功: %s\n", test)
            if len(matches) > 1 && matches[1] != "" {
                fmt.Printf("  捕获的资源: %s\n", matches[1])
            }
        } else {
            fmt.Printf("匹配失败: %s\n", test)
        }
    }
}

输出结果:

匹配成功: /user/action
匹配成功: /user/action/someResource
  捕获的资源: someResource
匹配失败: /user/actionblablablabla
匹配成功: /user/action/
  捕获的资源: 
匹配成功: /user/action/resource/subresource
  捕获的资源: resource/subresource

这个正则表达式确保:

  1. 只匹配以 /user/action 开头的路径
  2. 可选地匹配 / 后的任意内容作为资源路径
  3. 不会匹配 /user/actionblablablabla 这样的字符串
回到顶部