正则小剧场

正则小剧场 #

golang默认的正则,并非pcre正则,像正则断言的语法,golang就不支持

这里提供一个正则测试网站: regex101

零宽断言 #

零宽断言是匹配宽度为零,满足一定的条件/断言,通常用于查找在特定内容,该内容前或者后满足一定条件,但是匹配内容又不包括这些条件

零宽断言可以拆成两部分理解,零宽断言

  • 零宽: 代表满足条件,但是不作为匹配内容,看上去好像宽度为零
  • 断言: 声明一个应该为真的事实,只有当断言为真时才会继续进行匹配

断言条件所在的位置(前后)以及断言条件是否取反(正负),又可以将零宽断言分为四种: 负向先行/负向后发/先行/后发。

具体表达式:

  • (?=表达式)
  • (?!表达式)
  • (?<表达式)
  • (?<!表达式)

实践 #

提醒
macos系统的grep不支持-P选项,一下均使用linux中的grep测试,可以使用在线正则regex101网站进行测试

样本 #

$ cat > /tmp/text <<-EOF
> api01retcode000000
> api01retcode000001
> api01retcode000002
> api02retcode000000
> api02retcode000001
> api02retcode000002
> api03retcode000000
> api03retcode000001
> api02retcode000002
> EOF

先行正断言 #

# 先行正断言 retcode(?=000000)(\d{6})
$ grep -P 'retcode(?=000000)(\d{6})' /tmp/text
api01retcode000000
api02retcode000000
api03retcode000000

先行负断言 #

# 先行负断言 retcode(?=000000)(\d{6})
$ grep -P 'retcode(?!000000)(\d{6})' /tmp/text
api01retcode000001
api01retcode000002
api02retcode000001
api02retcode000002
api03retcode000001
api02retcode000002

后发正断言 #

# 后发正断言 (?<=api01)retcode(\d{6})
$ grep -P '(?<=api01)retcode(\d{6})' /tmp/text
api01retcode000000
api01retcode000001
api01retcode000002

后发负断言 #

# 后发负断言 (?<!api01)retcode(\d{6})
$ grep -P '(?<!api01)retcode(\d{6})' /tmp/text
api02retcode000000
api02retcode000001
api02retcode000002
api03retcode000000
api03retcode000001
api02retcode000002

非捕获分组 #

另外还有个不进行断言,而是作为非捕获分组存在,比如需要使用小括号进行或操作,但是不想改内容作为分组匹配内容时,可以使用,语法为:(?:mo|fa)ther