regexp - emacs 如何使用正则查找替换匹配组?

查看:172
本文介绍了regexp - emacs 如何使用正则查找替换匹配组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

例如有以下文档

1
1-1
1-1-1

经过查询替换后变为

#1
#1-1
#1-1-1

功能类似M-%,询问式替换,但是需要正则组。求方法
先感谢了!

解决方案

我在emacs学习笔记上的正则相关部分如下:(参考最后一个实例)

07-02) emacs正则表达式(regular expression)regexp

M-x re-builer  手动生成正则表达式
M-x regexp-builder 同上,手动生成正则表达式
M-x regexp-opt  根据目标内容生成对应的正则表达式
可以利用emacs的函数exgrep-opt自动生成一个高效的正则匹配表达式:

(regexp-opt '("foobar" "foobaz" "foo"))按键"C-x C-e"在状态栏生成正则表达式
(regexp-opt '("foobar" "foobaz" "foo"))按键"C-u C-x C-e"在当前光标处生成正则表达式
(regexp-opt '("foobar" "foobaz" "foo"))"\(?:foo\(?:ba[rz]\)?\)"

C-h s  (describe-syntax)显示在当前模式下的正则表达式规则描述
C-x w h   (highlight-regext)高亮显示正则表达式
C-x w r   (unhighlight-regext)取消高亮显示正则表达式
M-x list-matching-lines   显示包含正则表达式的整行
`\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}' 显示包含IPv4格式地址的行
注:在elisp代码中需要用2个反斜线\\进行转义,而在minibuffer中输入时,只需要1个\进行转义
在重复进行正则表达式操作时,可以直接用上、下光标按键,查看正则表达式的历史匹配记录

特殊字符在Emacs正则表达式中的含义:
"." 匹配除了换行符之外任何单个字符的特殊字符。
"*" 自身不构成表达式的部分,是个后缀操作符,表示某个前导表达式重复任意次。
"+" 后缀操作符,与*作用相同。
"?" 后缀操作符,与"*"作用相似,匹配前导表达式至多出现1次(0次或1次重复)
"?,+?,??" 是前几个操作符的非贪心变体。正常的/+/?操作符是贪心的,只要总体上能够匹配,总是尽可能多的匹配。当有一个紧跟着?时就是非贪心:尽可能少的匹配。如:ab和ab?都能匹配a和abbbb,但同时多个匹配对象时,ab将匹配最长有效匹配abbbb,而ab?匹配最短有效匹配,仅匹配a。

"{N}" 指定重复次数为N的后缀操作符,前导表达式匹配了N次。
"{N,M}" 指定重复次数在N和M之间的后缀操作符,前导表达式至少匹配N次,但不超过M次。
"[ ... ]" 字符集范围,以["开始,以"]"结束,在两个方括号中间的字符就是这个集合能匹配的全部。可以用"-"放在开始字符与结束字符中间来指定匹配范围,如[a-z]匹配所有小写字母。字符集中的特殊字符:通常在字符集中的特殊字符不再特殊,但"]", "-", "^"情况特殊,如果想在集中包括"]"必须把它作为字符集中的第一个字符;想包括"-"必须把它作为字符集中的第一个或最后一个字符;想包括"^"必须把它放在除第一个字符以外的任何地方。
"1" 表示补集合,即匹配的字符是除掉指定的字符外其它所有的字符,"2"表示匹配除ASCII字母和数字外的所有字符。
"^" 仅匹配在文本中行首的那个空串的特殊字符
"$" 仅匹配行尾的空串
"" 引用特殊字符,包括"",如"$", "[";
"`" 匹配空串,但仅是接在缓冲区的开始处的。
"'" 匹配空串,但仅是接在缓冲区的尾部的。
"=" 匹配空串,但仅在"点"处的。
"b" 匹配空串,但仅在一个词的开始或者结尾的,如"bfoob"匹配任何作为单独的词出现的foo;"bballs?b"匹配作为单独的词出现的ball或balls。
"B" 匹配空串,但不在词的开始或结尾处。
" 匹配空串,但仅在词的开始处。仅当一个构成词的字符在缓冲区开始处时"\
">" 匹配空串,但仅在词的结尾处,仅当缓冲区尾部有构成词的字符时">"匹配缓冲区尾部的空串。
w" 匹配任何构成词的字符,由语法表决定这些字符是什么。
"W" 匹配任何非构成词的字符
"sC" 匹配任何语法是C的字符,这里C是一个指定特定语法类的字符,如"w"为词的构成字符,"-"或" "为空白, "."为普通标点符号。
"SC" 匹配任何字符不属于语法C
"cC" 匹配任何属于种类C的字符,如"cc"匹配汉字, "cg"匹配希腊字符,用M-x describe-categories或查看已知种类。
"CC" 匹配所有不属于种类C的字符

|产生附加的特殊结构:
"|" 指定一个选择 A | B 在表达式A与B中间时,首先匹配表达式A,如果匹配失败再匹配表达式B。"|"作用于两边最长可能的表达式,但是由"(...)"可以限制"|"的分组能力。
"(...)"分组结构有三种功能:
围住"|"的选择项: "(foo|bar)x" 可以匹配foox或者barx
围住复杂的表达式以实现后缀操作符(如"" "+" "?")的操作: "ba(na)匹配如bananana等有任意个"na"串记录一个已匹配的子串用作后面的参考引用(并不是括号的n分组功能思想的结果)实际应用中,分组功能与匹配参考引用就注意,避免发生冲突,可以使用谨慎的分组"(?:...)",谨慎的分组不记录匹配的子串,不能用D来引用,在机械的结合正则表达式的时候有用,这样可以为语法目的加入分组,而不用干涉使用者写的分组的个数。
"D" 匹配和"(...)"结构第D次出现时所匹配的同样的文本。在"(...)"结构结束之后,匹配程序保存被这个结构匹配的文本,之后的正则表达式中,可以使用""跟着一个数字D来表示匹配和之前匹配结构第D次出现时所匹配的同样的文本。"(.*)1"匹配任何有完全相同的两部分而无换行符的串,"(...)"匹配前一半,可以是任意的串,"1"匹配后面的串,但必须和前面的完全相同。

与正则表达式相关的函数:

C-M-s  isearch-forward-regexp向前正则匹配
C-M-r  isearch-backward-regexp向后正则匹配
M-x    query-replace-regexp正则查询替换(对于每一次替换都要确认)
M-x    replace-regext正则替换(直接替换全部匹配的所有,不需要确认)

正则表达式应用实例:

[a]正则搜索内容为"空格"或"<TAB>":
按键:C-M-s: \|<tab>
按键说明:第1个按键为空格" ",第2个按键为"\|"是或者的意思,第3个按键为<TAB>,显示为"^I"。
Regexp I-search: \|^I

[b]正则搜索内容为"回车":
按键:C-M-s:C-q C-j,显示为^J
Regexp I-search: ^J

[c]正则搜索内容为Tab制表符:
按键:C-M-s:<tab>,显示为^I
Regexp I-search: ^I

[d]查找IPv4格式的IP地址:
按键:C-M-s:\\(\[0-9\]\\{1,3\\}\\.\\)\\{3\\}\[0-9\]\\{1,3\\}
61\.139\.[0-9]\{1,3\}\.[0-9]\{1,3\}

[e]正则替换IP地址:(将所有61.139.*.* 替换为1.2.3.4)
按键:C-M-%:61\.139\.[0-9]\{1,3\}\.[0-9]\{1,3\}<RET>1.2.3.4
Query replace regexp (default 61\.139\.[0-9]\{1,3\}\.[0-9]\{1,3\} -> 1.2.3.4:

[f]正则替换:将多个空格或者TAB替换为1个空格
按键:C-M-%:[ C-q<TAB>]+<RET> <RET>
Query replacing [ ^I]+ with  : (? for help)
按键:C-M-%:
Query replace regexp (default [ ^I]+ ->  ): 

[g]正则替换:将从eshell下执行的命令结果拷贝至记录文件中后,替换掉命令结果中的shell命令提示符( /mnt/sda5d/TDDownload/shell $  替换为 shell# )
按键:C-M-%:^/.* \$<RET>shell#<RET>
Query replace regexp (default ^/.* \$ -> shell#): 

[h]正则搜索所有"空格+行尾"(行尾以空格结束,在vim中是/ $):
按键:C-M-s: +$

[i]正则替换:将多个空行替换为1个空行
按键:M-x replace-regexp:^C-q C-j $<RET><RET>
按键说明:^表示以什么开始,C-q C-j联合按键是一个回车,$表示行尾
Replace regexp (default ^^j$ -> ):

[j]正则替换:使用()()进行分组交换(将单词与冒号的组合abc:进行交换: abc)
按键:M-x replace-regexp:\([a-z]\{1,999\}\)\(\:\)<RET>\2 \1<RET>
按键说明:\(.....\)表示第1个分组,后面可以跟多个分组\(....\)\(.....\)在替换时分别以\1\2\3来表示之前定义的各个分组。

[k]正则替换:将css文件中abc{中间加个空格abc {
按键:M-x replace-regexp:\([a-z]+\)\({\)<RET>\1 \2<RET>
按键说明:在\(.....\)编组之间的字符直接用字符即可,不用加上\转义

[l]正则替换:将所有单词的首写字母替换为首写字母大写
按键:M-x replace-regexp:\(\w+\)<RET>\,(capitalize \1)<RET>
按键说明:在替换部分\,表示后面跟的不是要用来替换的东西,而是一段lisp程序

[m]正则替换:将所有匹配的文字后面加上一个回车
按键:M-x replace-regexp:\([a-z]+\)\({\)<RET>\&C-qC-j<RET>
按键说明:在替换部分用\&表示前面匹配的所有文字

[n]正则替换:将所有匹配的1 1-1 1-1-1替换为#1 #1-1 #1-1-1
按键:M-x replace-regexp:\(\([0-9]+\-\)*[0-9]+\)<RET>#\1
原文为:
1
1-1
1-1-1
asfa saf  232-33, 11-22-33-44
smesf ijds  101-22-33-23
替换后:
#1
#1-1
#1-1-1
asfa saf  #232-33, #11-22-33-44
smesf ijds  #101-22-33-23


  1. ...
  2. a-z0-9A-Z

这篇关于regexp - emacs 如何使用正则查找替换匹配组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆