Emacs使用教程(八)

查找替换是任何编辑器都不可能缺少的功能,就连小小的Notepad都有快速查找,更不用说像Emacs这样的庞然大物了。其重要性这里就不多说了,接下来将一步一步给你介绍如何在Emacs中进行查找和替换。

  Emacs将查找分成了四个大类,分别是:简单查找,增量查找,词组查找和正则查找。四种方式各有特点,适用范围也不同,大家根据需要熟悉一两种即可。

​一、增量查找 

   先介绍增量查找的原因是这个是用的最多的查找方式,使用也很方便,直接C-s (isearch-forward)便进入增量查找状态,Minibuffer出现如下提示: 

 

   其实增量查找很好理解,就是边输入边查找,在输入的过程中离光标最近的匹配会用深色高亮,一屏中其它的匹配字符串会浅色高亮,参见这张图:

 

  只要是单词中包含”to” 的都会标记出来,比如tutorial。在输入查找字符串过程中可以随时用Backspace删除输入字符,当输入完成后按下回车会定位到向前最近的匹配字符串,并出现提示“Mark saved where search started”,就是说将你开始查找时光标所在位置加入了标记环,我们可以通过C-u C-@回到那个点。如果没找到字符串提示为“Failing I-search”,后接查找内容。C-s搜索时是向前进行查找,我们还可以使用C-r (isearch-backward)向后进行查找,注意这种方式的查找光标会定位到匹配字符串的最前方。虽然查找过程只会向一个方向进行,但到了文档底部或者头部还是会回到文档的头或底继续找,这就是常说的循环查找。

  在搜索的过程中并不一定第一个匹配项就是我们需要的内容,或者说我们需要找的地方不止一处,这样我们想能够快速的定位到下一个匹配项位置,解决办法也很简单,接上例我们输入”to”后不要急着按回车,而是再用C-s就会向后定位,或者用C-r 向前定位,总之停到你想要的地方为止。另外,如果你退出了这次的查找,后面又想找同一个东西,那么使用C-s C-s 即可,同理C-r C-r 。

  Emacs在多次查找的过程中会维护一个查找环(search ring) ,这是我们见到的第三个环了,前面两个是mark ring、kill ring。在输入C-s后,使用M-n和M-p可以调出查找环中上一个和下一个查找的内容。虽然这个也叫环但它是个标准的队列,有头有尾不会循环。

  在增量查找中还有些特殊的功能:通常查找时是忽略了大小写的,但如果我们输入的查找内容有小写字母还有小写字母,Emacs会自动进入大小写匹配查找状态中;也可以在查找的过程用M-c 快速切换是否大小写敏感,不过只对此次查找启用;如果我们想找回车符用C-j 代替;还可以使用M-Tab (isearch-complete)对查找进行自动完成,候选项是查找环中的东西,当然你用M-Tab 是没效果的,用了后连Emacs都不在了,我们需要对isearch-complete重新绑定;在增量查找状态中按C-h C-h 会进入增量查找的帮助,里面的内容大家可以自己研究;使用C-w 可以将光标处单词复制到查找区域中进行快速输入,这个功能比较常用;与其类似的是C-y 它能够把光标所在处直到行尾的内容都复制到查找区域,提醒一点这两个命令在复制的过程中会把所有字母变成小写;M-y 还能把kill 环里的内容复制到查找区域;C-M-w 用于删除查找区域中最后一个字符;而C-M-y 把光标处字符复制到查找区域最后;复制光标处的字符还有个方法,进入增量查找状态后,首先按M-e 定位到查找区域的最后,再使用C-f 就可以开始复制了。

 

二、简单查找

  简单查找顾名思义就是简单的查找方式(其实不一定有增量查找来的快),有时候又叫它非增量查找。使用命令是C-s RET string RET ,首先用C-s调出增量查找,然后回车取消掉进入简单查找,再输入需要查找的字符串,最后回车Emacs会向后开始找,直到第一个满足的字符串后面。大家在按命令的过程中可以观察Minibuffer中的提示,按下C-s后,会出现一个蓝色的“I-search:”,回车后变为“Search:”,当找到所输入的内容后出现提示“Mark saved where search started”,其实简单查找和增量查找大部分都没什么区别,增量查找中命令基本上这儿也能用,最大的区别就是等你输入完成后它才开始搜索,还有一点就是没有高亮。向前查找的话一回事,C-r RET string RET 。向后向前分别对应命令search-forwardsearch-backward

 

三、词组查找

  词组查找一般用在大段文本编辑中,比如写新闻、写信之类的。它在查找的过程中会忽略掉一些标点符号,比如换行符,逗号,句号之类的,查找时也是进行的增量查找,边输入边找,不过对于单词来说是全词匹配。其命令是M-s w (isearch-forward-word)。查找的示例如下图:

 

 

   我在找”it”的时候,红框圈出来的permitted并没高亮,而我输入”it under”时,逗号和回车符都忽略掉了,这些特点在查找大段句子的时候相当好用。词组查找也可以使用非增量搜索的方式,对应命令M-s w RET words RET (word-search-forward) ,向回找M-s w C-r RET words RET (word-search-backward),这里面的words就是你需要查找的词组。词组查找其余大部分使用方式和前面的类似就不多叙述了。

 

 四、正则查找

  这种查找方式使用正则表达式,功能相当的强大,其主要还是看各人正则表达式的水平了,Emacs中的正则语法放到后面再讲,这里只说下怎么调出正则查找。命令 C-M-s (isearch-forward-regexp),咳,用快捷键的时候把QQ关了,这个是向前找,命令可以看出来使用的是增量查找方式,向后是C-M-r (isearch-backward-regexp)。

 

五、替换

  本次的另一半内容就是介绍Emacs中的替换功能,就是将一个字符串变成另一个字符串。

  最简单粗暴的方式就是使用replace-string 这个命令,用法如下:M-x replace-string RET oldstring RET newstring RET,第一次回车输入需要替换的字符串,第二次回车输入想要变成的字符串,最后确认。它将会把所有匹配oldstring 的字符串全部替换掉,建议大家在没绝对把握前还是不要用这个的好。在替换的过程中Emacs对大小写有比较智能化的处理,比如输入M-x replace-string RET abc RET efg RET,所有的”abc”都变成了”efg”,但是”ABC”会替换成”EFG”,不止这样”aBc”会改为”eFg”,大写对大写,小写对小写。当然我们可能不想做这样的变化,那么把变量case-replace 设为nil 即可,还有个相关的变量case-fold-search ,设为nil后,它会在查找的时候就强制匹配大小写。

  暴力替换的正则版命令replace-regexp,用法和上面一样,只是oldstring改为正则表达式。

  实际上,我们在替换的时候并不希望所有的东西都换掉,还是想中间有个给自己判断选择的过程,在Emacs中称其为查找替换,M-% (query-replace) ,用的时候和前面一样,先输入oldstring,再输newstring,但是它是一个一个找的,对每个找到的匹配询问用户该如何处理,根据你的回答它再做出下个动作。下面这张表列出了所有可能的回答和相应。 

 

输入 响应
SPC 或者 y 替换当前匹配并前进到下一个匹配处
DEL 或者 n 忽略此次匹配并前进到下一个匹配处
. 替换当前匹配并退出
, 替换当前匹配并停在此处,再按y后前进
! 替换所有剩余匹配
^ 回到前一个匹配处
RET 或者 q 直接退出
e 修改新字符串
C-r 进入递归编辑状态
C-w 删除当前匹配并进入递归编辑状态
C-M-c 退出递归编辑状态,返回查找替换
C-] 退出递归编辑状态,同时退出查找替换
C-h 显示帮助

 

      这些命令中,相对y,n,q用的会多点。但如果按了任何其它的键都会退出查找替换状态,不小心退出后还能使用C-x ESC ESC返回。

      最后说下什么是递归编辑状态,简单的说就是你在查找替换的过程中突然发现需要修改点东西,但又不想直接退出查找替换,这时Emacs提供了一个临时的编辑状态可以让你先干刚想起的事,等你做完了还可以回到查找替换状态,这个临时的状态就叫递归编辑状态。

 

      注意看,这时mode line中的模式名外面加了一层方括号”[]”,标明进入了递归编辑状态。干完事后使用C-M-c 就可以回到前一个状态,实际上,在任何时候都可以用命令 recursive-edit 进入递归编辑,用abort-recursive-edit 或者top-level 退出,也可以用C-M-c 返回前一状态。

 

小结:

 

按键

命令

作用

C-s

isearch-forward

向前进行增量查找

C-r

isearch-backward

向后进行增量查找

M-c

 

(查找状态)切换大写敏感

C-j

newline-and-indent

(查找状态)输入换行符

M-Tab

isearch-complete (查找状态)自动匹配

C-h C-h

 

(查找状态)进入查找帮助

C-w   (查找状态)将光标处单词复制到查找区域
C-y   (查找状态)将光标处直到行尾内容复制到查找区域
M-y   (查找状态)把kill 环中最后一项复制到查找区域
C-M-w   (查找状态)删除查找区域最后一个字符
C-M-y   (查找状态)将光标处字符复制到查找区域最后
C-f   (查找状态)将光标处字符复制到查找区域最后
C-s RET search-forward 向前进行简单查找
C-r RET search-backward 向后进行简单查找
M-s w isearch-forward-word 向前进行词组查找
M-s w RET word-search-forward 向前进行词组查找(非增量方式)
M-s w C-r RET word-search-backward 向后进行词组查找(非增量方式)
C-M-s isearch-forward-regexp 向前进行正则查找
C-M-r isearch-backward-regexp 向后进行正则查找
  replace-string 全文替换
  replace-regexp 全文正则替换
M-% query-replace 查找替换
  recursive-edit 进入递归编辑
  abort-recursive-edit 退出递归编辑
  top-level 退出递归编辑

 

 

 

 

变量

作用

case-replace 设置大小写自动替换
case-fold-search 设置大小写匹配查找

 

 

 

发布者

混沌未开

一个经常性心血来潮的收藏狂,希望能通过自己所学所见来获得周遭孩纸的认可……