package main import ( "fmt" "regexp" "unicode/utf8" ) func main() { // 测试场景1 text1 := "余额200,积分50,代金券80" // 测试场景2:两个50,一个积分、一个代金券 text2 := "余额200,积分50,代金券50" fmt.Println("场景1结果:", filterNotScoreNum(text1)) fmt.Println("场景2结果:", filterNotScoreNum(text2)) } // filterNotScoreNum 过滤:数字前面紧邻是“积分”的数字剔除,等价 (?!积分) 反向语义 func filterNotScoreNum(text string) []string { numRe := regexp.MustCompile(`\d+`) indexList := numRe.FindAllStringIndex(text, -1) var validNums []string for _, pos := range indexList { startIdx, endIdx := pos[0], pos[1] numStr := text[startIdx:endIdx] // 读取数字前面的上下文,倒推判断前面是不是“积分” // 从数字开头位置向前读取2个汉字的符文长度 beforeStr := text[:startIdx] // 倒着解码两个rune runeCnt := 0 var lastTwoRunes []rune // 反向遍历符文 for i := len(beforeStr); i > 0 && runeCnt < 2; { r, size := utf8.DecodeLastRuneInString(beforeStr[:i]) lastTwoRunes = append([]rune{r}, lastTwoRunes...) i -= size runeCnt++ } // 判断数字前两个汉字是否为“积分” isScoreNum := false if len(lastTwoRunes) == 2 { prefix := string(lastTwoRunes) if prefix == "积分" { isScoreNum = true } } // 不是积分对应的数字才保留 if !isScoreNum { validNums = append(validNums, numStr) } } return validNums }