我有一个需求,需要匹配一段字符串中第几季的这个几,那么按正则表达式的语法,我的表达式应该是这样的
`(?<=第)\d+(?=季)`
然而,当我用go官方包regexp的时候,compile的时候报了个错误:
(?<
啥意思呢?
语法错误,不支持(?<,然而我在线运行的时候明明是没错的,这说明go的正则引擎不支持负向预查。
通过查看文档发现同时也是不支持正向预查的,下面这些都是不支持的。
(?=re)re(?!re)re(?<=re)re(?
但是有些需求用预查确实很方便,比如我想查找“第3部”中的这个3,如果有预查我只需要
(?<=第)[0-9]+(?=部)
这样就可以很简单的查到第和部之间的这个数字,而没有预查的话难道要我先查到第再查部,记录他们的位置去查3吗?
这简直不科学!
我相信前辈们肯定遇到过这个问题而且已经造好轮子了,所以立马去GitHub搜,果然没让我失望,找到了
regexpregexpregexpregexp
用法:
regexpCompileMustCompileregexp
如何引入:
import “github.com/dlclark/regexp2”
go get -u github.com/dlclark/regexp2
比如:
var res string
str := "公众号:codeoffer。"
expr:= `(?<=公众号:).*(?=。)`
reg, _ := regexp2.Compile(expr, 0)
m, _ := reg.FindStringMatch(str)
if m != nil {
res = m.String()
}
fmt.Println(res)
输出:
codeoffer
这里和regexp的用法有稍微不一样的地方,比如Compile的时候需要传两个参数,第二个RegexOptions表示。。。
默认为0即可,然后匹配后返回的结果是一个group的结构,如果想真正获得结果需要进行一个string(),
m.String()m.Group.String()m.Groups()[0].String()
if m, _ := re.FindStringMatch(`Something to match`); m != nil {
// the whole match is always group 0
fmt.Printf("Group 0: %v\n", m.String())
// you can get all the groups too
gps := m.Groups()
// a group can be captured multiple times, so each cap is separately addressable
fmt.Printf("Group 1, first capture", gps[1].Captures[0].String())
fmt.Printf("Group 1, second capture", gps[1].Captures[1].String())
}
比较regexp和regexp2
re.MatchTimeout(?Pre)(?re)(?'name're)(?#comment)(?|a|b)(?>re)(?=re)(?!re)(?<=re)(?
regexp2功能还是很强大的,如果是复杂的正则表达式推荐使用。