You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Golang regexp实现CV(N)(C)结构字符串的正确音节分割?

修正正则实现CV(N)(C)结构的音节正确分割

问题根源

原正则[ptk][aeiou][mn]?[ptk]?采用贪婪匹配逻辑,当字符串包含多个音节时,会把属于下一个音节的起始辅音(C)当作当前音节的可选结尾C消耗掉,导致后续字符无法匹配成完整音节。比如tanpa中,原正则会匹配tanp(把pa的p当作tan的可选结尾C),而非预期的tan+pa。

解决方案

通过正向否定预查限制结尾可选C的匹配条件:确保该C后面不是另一个音节的起始(即不跟着C+V),避免抢占下一个音节的起始辅音。

调整后的正则表达式结构为:

(CV(?:N)?(?:C(?!CV))?)

其中:

  • CV(?:N)?:匹配基础的CV或CVN结构
  • (?:C(?!CV))?:可选匹配结尾C,但通过(?!CV)确保这个C后面没有新的C+V音节起始,避免贪婪消耗下一个音节的C。

修改后的代码

package main

import (
	"fmt"
	"regexp"
	"strings"
)

func main() {
	words := []string{"ta", "tan", "tank", "tapa", "tanpa", "tankpa", "tapam", "tanpam", "tankpam", "tapamt", "tanpamt", "tankpamt", "tapitetot"}
	expected := []string{"ta", "tan", "tank", "ta.pa", "tan.pa", "tank.pa", "ta.pam", "tan.pam", "tank.pam", "ta.pamt", "tan.pamt", "tank.pamt", "ta.pi.te.tot"}

	C := "[ptk]"
	V := "[aeiou]"
	N := "[mn]"
	// 调整正则,加入正向否定预查限制结尾C的匹配
	cvnc := regexp.MustCompile(fmt.Sprintf("(%s%s%s?(?:%s(?!%s%s))?)", C, V, N, C, C, V))

	for i := range words {
		fmt.Println(words[i], "\n    expect", strings.Split(expected[i], "."), "\n    got   ", cvnc.FindAllString(words[i], -1))
	}
}

验证结果

修改后运行代码,所有案例均可得到预期的分割结果:

  • tanpa → ["tan", "pa"]
  • tapitetot → ["ta", "pi", "te", "tot"]
  • 其他单音节或多音节案例均符合预期输出。

内容的提问来源于stack exchange,提问作者bigyihsuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:20:29