Golang正则表达式返回错误结果怎么办

Golang正则表达式返回错误结果怎么办 我有以下代码:

package main

import (
	"fmt"
	"regexp"
)

func main() {
    // 第一部分
	s := "Never say never."
	r := regexp.MustCompile(`(?i)^n`)  // 开头是否有 'N' 或 'n'?
	fmt.Printf("%v", r.MatchString(s)) // true,不区分大小写,正确答案
	fmt.Println()

    // 第二部分
	r = regexp.MustCompile(`^a.b$`)
	matched := r.MatchString("aaxbb")
	fmt.Println(matched)  // false,为什么?
	fmt.Println()

    // 第三部分
	re := regexp.MustCompile(`.(?P<Day>\d{2})`)
	matches := re.FindStringSubmatch("Some random date: 2001-01-20")
	dayIndex := re.SubexpIndex("Day")
	fmt.Println(matches[dayIndex]) // 20,正确答案
	fmt.Println()

    // 第四部分
	re = regexp.MustCompile(`^card\s.\s(?P<Day>\d{2})`)
	matches = re.FindStringSubmatch("card Some random date: 2001-01-20")
	dayIndex := re.SubexpIndex("Day")
	fmt.Println(matches[yearIndex]) // panic: runtime error: index out of range [1] with length 0,为什么?
}

第一部分和第三部分没问题,返回了正确答案。 第二部分和第四部分是错的,要么返回错误答案,要么返回错误,尽管它们与第1和第3部分几乎相同,只是做了细微调整?


更多关于Golang正则表达式返回错误结果怎么办的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

hyousef:

    // Second part 
	r = regexp.MustCompile(`^a.b`)
	matched := r.MatchString("aaxbb")
	fmt.Println(matched)  // false, why?

你的正则表达式要求“以 a 开头,中间有一个任意字符,以 b 结尾”。所以它只会匹配恰好长度为 3 个字符的字符串。根据具体需求,你可能想使用 .+.*

hyousef:

	re = regexp.MustCompile(`^card\s.\s(?P<Day>\d{2})`)

这里你再次要求匹配一个被空格包围的单个字符。你可能又需要对 . 使用 +* 量词。在这种情况下,你还需要非常注意贪婪匹配与否。而且,即使你使用 ^card\s.*\s(?P<Day>\d{2}),它也不会给出你期望的结果!是的,在你这个特定的例子中,匹配结果会是 20,但这不是你以为的那个 20

可以在这里查看一下:

regex101: build, test, and debug regex

正则表达式测试器,支持语法高亮、解释、PHP/PCRE、Python、GO、JavaScript、Java、C#/.NET、Rust 的速查表。

更多关于Golang正则表达式返回错误结果怎么办的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在正则表达式模式与输入字符串的匹配逻辑上。以下是具体分析和修正:

第二部分问题^a.b$ 匹配以 “a” 开头、任意单个字符、以 “b” 结尾的字符串。而 “aaxbb” 包含 5 个字符,模式中的 . 只能匹配一个字符,导致整体不匹配。

修正示例:

r = regexp.MustCompile(`^a.*b$`) // 使用 * 匹配任意数量字符
matched := r.MatchString("aaxbb")
fmt.Println(matched) // true

第四部分问题:模式 ^card\s.\s(?P<Day>\d{2}) 要求字符串以 “card” 开头,后接空格、单个任意字符、空格,最后是两位数字。但输入字符串 “card Some random date: 2001-01-20” 在 “card” 后的空格后是 “Some”(4个字符),导致匹配失败,FindStringSubmatch 返回空切片。

修正示例:

re = regexp.MustCompile(`^card\s.*\s(?P<Day>\d{2})`) // 使用 .* 匹配任意字符序列
matches := re.FindStringSubmatch("card Some random date: 2001-01-20")
if matches != nil {
    dayIndex := re.SubexpIndex("Day")
    fmt.Println(matches[dayIndex]) // 20
}

关键点:

  1. . 仅匹配单个字符(换行符除外)
  2. FindStringSubmatch 返回 nil 时表示无匹配,直接索引会导致 panic
  3. 使用 .*.+ 进行贪婪匹配时需注意边界条件
回到顶部