vim正则零宽断言疑问

sh/bash/dash/ksh/zsh等Shell脚本
回复
ps3wifi
帖子: 94
注册时间: 2010-01-08 13:09

vim正则零宽断言疑问

#1

帖子 ps3wifi » 2020-05-30 22:01

xxx111 xxx222
xxx=111 xxx=222
xxxyyy111
xxxyyy=111
xy=111

正则表达式之环视:
\@= 顺序环视,前面字符是重点
Eg: 查找字符small,并且后面是cat
/small\(cat\)\@=

\@! 顺序否定环视,前面字符是重点
Eg:查找字符small,并且后面不是cat
/small\(cat\)\@!

\@<= 逆序环视,后面字符是重点
Eg:查找字符cat,且前面是small
/\(small\)\@<=cat
\@<! 逆序否定环视
Eg:查找字符cat,并且前面不是small
/\(small\)\@<!cat

正在学习正则表达式,发现vim的零宽断言与perl表达式不一样::19s/\(\(xy\)\@<==111\)\@=匹配到=等号,这个=是怎么匹配来的有点复杂看不懂了,烧脑了另外就是直接:19s/\(small\)cat\@=匹配到smallca,19s/\(smallcat\)\@=匹配到s,放到捕获组中的字符串匹配规则好奇怪,麻烦那位老师能帮我解答解答谢谢
头像
astolia
论坛版主
帖子: 6569
注册时间: 2008-09-18 13:11

Re: vim正则零宽断言疑问

#2

帖子 astolia » 2020-05-31 21:56

ps3wifi 写了: 2020-05-30 22:01 \(\(xy\)\@<==111\)\@=匹配到=等号,这个=是怎么匹配来的有点复杂看不懂了
并没有匹配到等号。
首先\(xy\)\@<==111这个匹配到你上面最后一行中的=111。这个你应该不会有问题
然后\(\(xy\)\@<==111\)\@=,因为最前面没有其他字符,所以它的意思是匹配一个空文本,这个空文本后面要求是=111。
所以实际匹配到的是xy和=111之间的空文本。但在normal模式下,光标只能停在=上而已。
你可以用:%s/\(\(xy\)\@<==111\)\@=/a/来验证,它实际效果是把xy=111改成了xya=111


ps3wifi 写了: 2020-05-30 22:01 直接:19s/\(small\)cat\@=匹配到smallca,19s/\(smallcat\)\@=匹配到s,放到捕获组中的字符串匹配规则好奇怪
你看起来没有理解到这句话
\@= 顺序环视,前面字符是重点
\(small\)cat\@=里面,\@=前面的字符是单个字符t,也就是查找smallca,要求后面是t,捕获组1里是small
\(smallcat\)\@=里面,\@=前面的字符是一个组\(smallcat\),也就是查找一个空文本,要求后面是smallcat,捕获组1里是smallcat
ps3wifi
帖子: 94
注册时间: 2010-01-08 13:09

Re: vim正则零宽断言疑问

#3

帖子 ps3wifi » 2020-06-01 0:09

谢谢版主的解答,但还是有一个不明白的地方\(small\)cat\@=前面是cat,small是在捕获组中,怎么会是单个字符t ???
版主还有另外一个vim问题,vim vistual模式下可视化块我选中的部分怎么替换为新内容,I和A都只能在选中部分前面或者后面插入内容,r又只能把所选块替换为单个字符,比如
xxx111
xxx222
我选中xxx替换为abc,该怎么快捷的操作?不用s命令的话
头像
astolia
论坛版主
帖子: 6569
注册时间: 2008-09-18 13:11

Re: vim正则零宽断言疑问

#4

帖子 astolia » 2020-06-01 10:27

ps3wifi 写了: 2020-06-01 0:09 谢谢版主的解答,但还是有一个不明白的地方\(small\)cat\@=前面是cat,small是在捕获组中,怎么会是单个字符t ???
astolia 写了: 2020-05-31 21:56 你看起来没有理解到这句话
\@= 顺序环视,前面字符是重点
“前面字符”,虽然这个说法不准确,但它也没说是前面的捕获组。不要跟着例子来学机制。再去读一下30分钟正则表达式教程,看看零宽断言作用范围是什么。
ps3wifi 写了: 2020-06-01 0:09 版主还有另外一个vim问题,vim vistual模式下可视化块我选中的部分怎么替换为新内容,I和A都只能在选中部分前面或者后面插入内容,r又只能把所选块替换为单个字符,比如
xxx111
xxx222
我选中xxx替换为abc,该怎么快捷的操作?不用s命令的话
为什么不用s?
选中后,按c,输入abc,按esc
选中后,按:,输入s/xxx/abc/,回车
头像
jiandan23
帖子: 86
注册时间: 2010-12-17 22:31
系统: Mint 19.2

Re: vim正则零宽断言疑问

#5

帖子 jiandan23 » 2020-06-03 17:29

下面这两种场景用\zs,\ze去做更加容易理解------------
(\zs代表真正匹配的开始,\ze代表真正匹配的结束)

正则表达式之环视:
\@= 顺序环视,前面字符是重点
Eg: 查找字符small,并且后面是cat
/small\(cat\)\@=
/\zssmall/zecat

\@<= 逆序环视,后面字符是重点
Eg:查找字符cat,且前面是small
/\(small\)\@<=cat
/small\zscat\ze
回复