Files
bulma/regexp/regexp_demo_10.go
T

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
}