VIM是我最喜欢用来搜索和替代文字的工具。这是最古老的文字编辑软件,也许许多人刚刚开始使用时为其用户界面所困扰,但是这是一个具有非常强大功能的软件,最初是由UNIX下的许多软件高手推出,经过多年来的补充和改进,现在几乎在所有的平台都可以下载免费的软件,它是许多编程人员爱不释手的高效率工具软件。
我最近遇到的问题是在众多的源程序中寻找满足tablespace的单字,但其后面的词不是以t开头的词。比如说tablespace temp就不是我需要寻找的内容,而tablespace pmdb就是我希望找到的内容。确认所有这些找到的内容之后,我需要将它们更换为我需要的内容。如果手动在几百个源程序中一一寻找,其工作量是非常巨大的。因此我想到了VIM。
VIM的基本搜索方式
首先回到VIM是基本搜索方式,下面是如何在VIM进行搜索的指令:/pattern
这里/是表示开始进行搜索,pattern是搜索的内容或模式,这个模式可以是Regex表达式。Regex是编程中非常强大用于表达搜索内容的表达式,有关这一方面的内容可以十分丰富,这里就不再相信解释了。
环顾继续搜索
我所需要的搜索不仅仅是满足一个模式,而是在满足模式部分内容的条件下,进一步要求不含有某些内容,比如满足tablespace,但其后不包括有t开头的词。我最初以为在VIM中有这样搜索的模式,但是经过网络搜索和研究之后,我发现VIM在处理这个问题上采用的是更为巧妙的方式。这就是lookahead zero width assertion或lookbehind zero width assertion,简言之,是进一步搜索前或后的内容作为搜索的满足条件,但是这种进一步的搜索的内容,不作为最后的搜索结果,因此称之为zero width,assertion是符合或不符合的意思。我这里将这些搜索的方式通称之为环顾继续搜索。
环顾继续搜索的表达方式为下面四种情况:
/PATTERN[ZERO_WIDTH_ATOM\@=]
/PATTERN[ZERO_WIDTH_ATOM\@!]
/[ZERO_WIDTH_ATOM\@<=]PATTERN
/[ZERO_WIDTH_ATOM\@
其中pattern是搜索的内容,搜索的结果将在VIM中标示出来,而zero width atom是进一步搜索的条件:或前或后,atom是VIM中的术语,表示一个字符或一个组;其搜索的条件是满足或不满足。这里我将这些特殊的表述总结为下面的表:
\@ | 表述向前 lookahead |
\@ | 表示向后 lookbehind |
= | 符合 positive match |
! | 不符合 negative or not match. |
用编程的逻辑来理解VIM的搜索
这里我可以用下面的c风格表述程序(pseudo codes)来描述VIM的搜索逻辑:Results getMatchedResults( string context, // basic string pattern, string zero_width_pattern, // zero_width pattern bool match_zero_width_pattern, bool lookahead) { results = EMPTY_LIST; result = getMatchedResult(context, pattern); while (result != EMPTY) { if (zero_pattern != EMPTY) { if ( lookahead ) { context_tmp = getNextContextByLookahead(context, result); result_tmp = getMatchedResult(context_tmp, zero_width_pattern); } else { context_tmp = getNextContextByLookbehind(context, result); result_tmp = getMatchedResultByLookbehind(context_tmp, zero_width_pattern); } if ( result_tmp == EMPTY ) { if (match_zero_width_pattern) { result = EMPTY; }
} else { if (!match_zero_width_pattern) { retult = EMPTY; } } } if ( result != EMPTY ) { results.add(result); context = geNextContextByLookahread(context, result); result = getMatchedResult(context, pattern); } } return results; }
上面的表述程序非常直观地解释了VIM的搜索逻辑,这里不必详细解释了。下一文将就此应用举出数个例子,届时将可以看到VIM搜索的强大功能。
参考
- VIM 文件: pattern and zero width
- René 文章 on VIM Search
- Regular-Expression.Info: Lookahead and Lookbehind Assertions
No comments:
Post a Comment