vim 环视,否定匹配

 

vimPerl意义例子
\@=(?=顺序环视查找后面是sqlmy/my\(sql\)\@=
\@!(?!顺序否定环视查找后面不是sqlmy/my\(sql\)\@!
\@<=(?<=逆序环视查找前面是mysql/\(my\)\@<=sql
\@<!(?<!逆序否定环视查找前面不是mysql/\(my\)\@<!sql
\@>(?>固化分组 
\%(atom\)(?:非捕获型括号(此分组不捕获,可以理解为不算在分组信息中):%s/\%(my\)sql\(ok\)/\1这个命令会将mysqlok替换为 ok ,由于my为捕获在分组中,故组中\1ok

@谢谢,以下作者提供

作者:Yihulee
链接:https://www.jianshu.com/p/3abd6fbc3322
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

<think>我们正在处理关于Vim中精确匹配查找的问题。用户希望使用正则表达式在Vim中执行精确查找匹配。 根据引用[5]:Vim中搜索的基本命令是: /pattern 向前搜索 ?pattern 向后搜索 n 和 N 用于在匹配项间移动 精确匹配意味着我们可能希望匹配整个单词,或者匹配一个特定的模式而不包含其他字符。 在正则表达式中,精确匹配通常通过边界限定来实现。Vim支持正则表达式,但需要注意的是,Vim的正则表达式语法与Perl等语言略有不同(引用[3]中提到正则表达式有不同流派)。 在Vim中,我们可以使用以下方式实现精确匹配: 1. 使用单词边界:\< 和 \> 分别表示单词的开头和结尾。例如,要精确匹配单词"word",可以使用:/\<word\> 这样就不会匹配到"keyword"或"wording"等。 2. 如果我们要匹配一个特定的模式(不一定是单词),可以使用锚点: ^ 表示行首 $ 表示行尾 例如,匹配以"pattern"开头的行:/^pattern 匹配以"pattern"结尾的行:/pattern$ 3. 如果要匹配一个完整的单词,但该单词可能包含非字母字符(如连字符、数字等),则使用单词边界可能不够,因为单词边界只识别字母、数字和下划线(取决于'iskeyword'选项)的边界。这时,我们可以使用更通用的零宽度断言,如\zs和\ze来指定匹配的开始和结束位置,或者使用环视(但Vim环视语法是\@<=和\@=等,比较复杂)。 用户问题中要求使用正则表达式进行精确匹配查找,因此我们主要使用单词边界或锚点。 另外,引用[1]和[4]中给出了一些使用正则表达式的例子,比如删除重复单词的命令中使用了\(\w\+\)\s\+\1,其中\w\+匹配一个单词,\1引用前面的匹配。 因此,针对用户的问题,我们可以给出如下解答: 在Vim中精确匹配查找命令(使用正则表达式): 1. 精确匹配整个单词:使用\<和\>包围要查找的单词。 例如,要查找单词"hello",使用:/\<hello\> 2. 精确匹配行首或行尾:使用^和$。 例如,查找以"hello"开头的行:/^hello 查找以"hello"结尾的行:/hello$ 3. 精确匹配任意字符串(包括非单词字符的完整匹配):我们可以使用^和$来匹配整行,但通常我们可能只需要匹配一个字符串而不考虑单词边界。这时,我们可以使用零宽度断言,例如: 要匹配字符串"abc.123"(注意中间有非单词字符),我们不能用单词边界,因为点号不是单词字符。我们可以直接匹配该字符串,但要注意字符串中可能包含正则表达式元字符,因此最好使用\V(即very nomagic)模式来避免转义。 例如:/\Vabc.123 但是,如果这个字符串出现在其他文本中间,我们可能还需要确保它不被其他字符包围。这时,我们可以使用环视(lookaround)来确保匹配的字符串前后没有其他字符(除了我们允许的)。但是Vim环视语法相对复杂,且用户要求精确匹配,所以我们可以用: /\(^\|\s\)abc.123\(\s\|$\) 这个表达式表示:匹配行首或空白字符开头,然后是字符串"abc.123",再后面是空白字符或行尾。但这样匹配会包含空白字符,所以如果我们不想包含空白字符,可以使用零宽度断言(Vim中称为原子的零宽度断言): /\<abc.123\> # 这不行,因为点号不是单词字符 /\(^\|\s\)\@<=abc.123\(\s\|$\)\@= # 这表示前面是行首或空白(但不消耗),后面是空白或行尾(但不消耗),这样匹配的就是abc.123本身。 然而,考虑到复杂性,对于非单词字符的精确匹配,通常建议使用单词边界(如果字符串由单词字符组成)或者直接匹配字符串(如果字符串是固定的,没有正则元字符)并确保上下文。 为了简化,我们可以这样建议: - 如果目标是一个由单词字符(字母、数字、下划线)组成的单词,使用\<word\> - 如果目标是一个固定的字符串(可能包含非单词字符),且不希望在它前后有其他非空白字符(即前后是空白或行首行尾),则使用:/\<pattern\> 可能不适用,我们可以用: /\(^\|\s\)pattern\(\s\|$\) 但这样会匹配到pattern前后的空白,如果我们只想高亮pattern,可以使用: /\<\pattern\> # 如果pattern包含非单词字符,则不能使用 或者使用: /\V\<pattern\> # 使用\V原义开关,这样只有$、\等少数字符有特殊意义,而.、*等就是普通字符。然后我们可以用\>来匹配单词边界?不,非单词字符不能用单词边界。 所以,对于包含非单词字符的精确匹配,我们可以使用环视(如果熟悉的话)或者直接匹配并手动检查上下文。 鉴于用户可能只是想要匹配一个完整的单词,我们重点介绍单词边界。 因此,回答如下:</think>### Vim 中精确匹配查找的正则表达式命令详解 在 Vim 中使用正则表达式进行**精确匹配查找**,主要通过以下关键命令实现: #### 1. **单词边界限定** 使用 `\<` 和 `\>` 锚定单词边界实现精确匹配: ```vim /\<exact_word\> ``` - **功能**:仅匹配完整单词(如 `\<word\>` 匹配 "word",不匹配 "keyword") - **示例**:查找 "var" 但不匹配 "variable" → `/\<var\>` - **原理**:`\<` 表示单词起始,`\>` 表示单词结束[^5] #### 2. **行首/行尾锚定** 使用 `^` 和 `$` 限定行位置: ```vim /^pattern$ " 匹配整行为pattern的行 /^pattern " 匹配行首为pattern /pattern$ " 匹配行尾为pattern ``` #### 3. **原义匹配模式** 用 `\V` 关闭正则元字符的特殊含义: ```vim /\V[exact.string] " 方括号[]内字符按字面匹配 ``` - **示例**:精确匹配 "[1.2]" → `/\V[1.2]`(避免 `.` 被解释为通配符)[^4] #### 4. **零宽断言** 高级场景使用环视断言: ```vim /\(pre\)\@<=target " 匹配前面是pre的target /target\(post\)\@= " 匹配后面是post的target ``` #### 操作流程示例 1. 进入命令模式按 `/` 启动搜索 2. 输入 `\<error\>` 精确匹配单词 "error" 3. 用 `n` 跳转到下一个匹配项,`N` 返回上一个 4. 按 `:set hlsearch` 高亮所有匹配项[^5] > **特殊场景**:匹配带连字符的单词(如 "end-to-end")需扩展单词边界定义: > ```vim > :set iskeyword+=- > /\<end-to-end\> > ``` --- ### 相关问题 1. 如何避免 Vim 正则中的特殊字符(如 `.`、`*`)被错误解析? 2. 在 Vim 中如何同时高亮并统计所有匹配项? 3. 多文件项目中如何实现跨文件的精确匹配搜索? [^1]: 边界锚定是正则表达式的核心功能,Vim 通过 `\<` 和 `\>` 实现单词级精确匹配 [^4]: 使用 `\V` 原义模式可关闭正则元字符的特殊含义 [^5]: Vim 的搜索命令配合正则边界限定可实现精准定位
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值