59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
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
|
|
}
|