VIM 用正则表达式 批量替换文本,多行删除,复制,移动

在VIM中 用正则表达式 批量替换文本,多行删除,复制,移动

:n1,n2 m n3     移动n1-n2行(包括n1,n2)到n3行之下;

:n1,n2 co n3    复制n1-n2行(包括n1,n2)到n3行之下;

:n1,n2 d        删除n1-n2行(包括n1,n2)行;

vi替换使用规则:
:g/s1/s/s2/s3/g

第一个g表示对每一个包括s1的行都进行替换,第二个g表示对每一行包括s1的行所有的s2都用s3替换
s表示替换,s2是要被替换的字符串,他可以和s1相同(如果相同的话用//代替),s3是替换字符串
在vi界面下使用命令 :%s#/usr/bin#/bin#g
可以把文件中所有路径/usr/bin换成/bin。其中“#”是转义字符,表明其后的“/”字符是具有实际意义的字符,不是分隔符。

s/str1/str2/ 用字符串 str2 替换行中首次出现的字符串 str1
:s/str1/str2/g 用字符串 str2 替换行中所有出现的字符串 str1
:s/str1/str2/gi 用字符串 str2 替换行中所有出现的字符串 str1,在查找时不区分大小写

(本文出自php_sir的新浪博客,用户名php_sir,首页链接:http://blog.sina.com.cn/phpsir,未经本人(php_sir)同意禁止转载)

: .,$ s/str1/str2/g 用字符串 str2 替换正文当前行到末尾所有出现的字符串 str1
:1,$ s/str1/str2/g 用字符串 str2 替换正文中所有出现的字符串 str1

:1,$ s/^str1/str2/g 用字符串 str2 替换正文中所有出现的,每行以str1开头的字符串
:g/str1/s//str2/g 功能同上
:%s/str1/str2/g 功能同上
:g/foobar/s/bar/baz/g 首先搜寻foobar,然后把它变成foobaz. 它没有改变 jailbars,
而其他的一些命令可能会改变jailbars.
:%s/str1/str2/gc 替换全文所有符合的单词并让用户确认
:g/str1/s//str2/gi 用字符串 str2 替换正文中所有出现的字符串
str1,在查找时不区分大小写,此命令没有下面的严格,经测试显示,不能完全做到在查找时忽略大小写
:%s/str1/str2/gi 用字符串 str2 替换正文中所有出现的字符串
str1,在查找时不区分大小写,在查找时可以完全做到忽略大小写
:10,20s/^/ / 将第10行至第20行资料的最前面插入5个空白
:%s/$/str/g 在整个文件每一行的行尾添加“str”
:3,7s/str1/str2/g仅替换文件中的第3行到第7行中的“str1”成“str2”
:%s/:.*//g
删除/etc/passwd中用户名后面的从冒号开始直到行尾的所有部分(前提是已经打开了/etc/passwd文件)

从上述替换命令可以看到:g
放在命令末尾,表示对搜索字符串在光标所在行的每次出现进行替换;不加 g,表示只对搜索字符串的首次出现进行替换;g
放在命令开头,表示对正文中所有包含搜索字符串的行进行替换操作。上面的命令中的/只是起分隔作用,也可以用其他的字符代替。另外,可以在正规式里用\
(和\)来剥离一个序列。

例如:有些字符域使用得很频繁. Vim 为这些字符域提供了预定义域:
项 匹配 相当于
\d 数字 [0-9]
\D 非数字 [^0-9]
\x 十六进制数字 [0-9a-fA-F]
\X 非十六进制数字 [^0-9a-fA-F]
\s 空白字符 [ ] ( 和 )
\S 非空白字符 [^ ] (非 和 )
\l 小写字母 [a-z]
\L 非小写字母 [^a-z]
\u 大写字母 [A-Z]
\U 非大写字母 [^A-Z]
& 所有查找时匹配到的东西
\[Ee] 更改大小写的选择区域的终点

:%s/\s\+$// 删除行尾多余的空格

命令前面指明范围是“%”,所以这会作用于整个文件。“substitute”命令的样式是“\s\+$”。这表示行末($)一个或者多个(\+)空格(\s)。:g/\(foo\)\(bar\)/s/\2/\1baz/g
将foobar替换成foobaz

www.qdtianquan.com

:0,$d   删除所有内容
:%s/r//g 删除DOS方式的回车^M
:%s= *$== 删除行尾空白
:%s/^(.*)n1/1$/ 删除重复行
:%s/^.{-}pdf/new.pdf/ 只是删除第一个pdf
:%s/// 又是删除多行注释(咦?为什么要说「又」呢?)
:g/s*^$/d 删除所有空行 :这个好用有没有人用过还有其他的方法吗?
:g!/^dd/d 删除不含字符串'dd'的行
:v/^dd/d 同上 (译释:v == g!,就是不匹配!)
:g/str1/,/str2/d 删除所有第一个含str1到第一个含str2之间的行
:v/./.,/./-1join 压缩空行
:g/^$/,/./-j 压缩空行
ndw 或 ndW 删除光标处开始及其后的 n-1 个字符。
d0 删至行首。
d$ 删至行尾。
ndd 删除当前行及其后 n-1 行。
x 或 X 删除一个字符。
Ctrl+u 删除输入方式下所输入的文本。
^R 恢复u的操作
J 把下一行合并到当前行尾
V 选择一行
^V 按下^V后即可进行矩形的选择了
aw 选择单词
iw 内部单词(无空格)
as 选择句子
is 选择句子(无空格)
ap 选择段落
ip 选择段落(无空格)
D 删除到行尾
x,y 删除与复制包含高亮区
dl 删除当前字符(与x命令功能相同)
d0 删除到某一行的开始位置
d^ 删除到某一行的第一个字符位置(不包括空格或TAB字符)
dw 删除到某个单词的结尾位置
d3w 删除到第三个单词的结尾位置
db 删除到某个单词的开始位置
dW 删除到某个以空格作为分隔符的单词的结尾位置
dB 删除到某个以空格作为分隔符的单词的开始位置
d7B 删除到前面7个以空格作为分隔符的单词的开始位置
d) 删除到某个语句的结尾位置
d4) 删除到第四个语句的结尾位置
d( 删除到某个语句的开始位置
d) 删除到某个段落的结尾位置
d{ 删除到某个段落的开始位置
d7{ 删除到当前段落起始位置之前的第7个段落位置
dd 删除当前行
d/text 删除从文本中出现“text”中所指定字样的位置,
一直向前直到下一个该字样所出现的位置(但不包括该字样)之间的内容
dfc 删除从文本中出现字符“c”的位置,一直向前直到下一个该字符所出现的位置(包括该字符)之间的内容
dtc 删除当前行直到下一个字符“c”所出现位置之间的内容
D 删除到某一行的结尾
d$ 删除到某一行的结尾
5dd 删除从当前行所开始的5行内容
dL 删除直到屏幕上最后一行的内容
dH 删除直到屏幕上第一行的内容
dG 删除直到工作缓存区结尾的内容
d1G 删除直到工作缓存区开始的内容

如何在Vim的正则表达式替换中使用字母大小写转换?

比如有下面这段文字:

every day

想将两个单词都转变为全大写,可以类似下面的vim最下行命令:

  1. :s/\(.*\) \(.*\)/\U\1 \2/

转变结果为:

EVERY DAY

相关的转义序列还有'\u','\L','\l'。

'\u'表示只将首字母大写;而'\L','\l'的含义是与'\U','\u'相反的。

下面的blog中包含了与上面相似的内容:

Vim中的正则表达式

不过要注意,此blog中在实验时是使用了模式分组来做的。上面的四个转义序列将在其被显式停止前,对跟在其后的内容持续作用;如果要停止,需要使用'\e'来中断。

比如想将上面的文字转变为:

EVERY day

则需要使用类似下面的方式:

  1. :s/\(.*\) \(.*\)/\U\1\e \2/

Vim用正则表达式进行批量修改

分类: Linux 2013-09-05 23:25 1208人阅读 评论(0) 收藏 举报

vim可以设置 magic 这个东西, magic就是设置哪些元字符要加反斜杠哪些不用加的。 简单来说:

magic(\m):除了 $ . * ^ 之外其他元字符都要加反斜杠。

nomagic(\M):除了 $ ^ 之外其他元字符都要加反斜杠。

这个设置也可以在正则表达式中通过 \m \M 开关临时切换。 \m 后面的正则表达式会按照 magic 处理,\M 后面的正则表达式按照 nomagic 处理, 而忽略实际的magic设置。
/\m.*          # 查找任意字符串
/\M.*          # 查找字符串 .* (点号后面跟个星号)

另外还有更强大的 \v 和 \V。 * \v(即 very magic 之意):任何元字符都不用加反斜杠 * \V(即 very nomagic 之意):任何元字符都必须加反斜杠
例如:
/\v(a.c){3}$   # 查找行尾的abcaccadc
/\m(a.c){3}$   # 查找行尾的(abc){3}
/\M(a.c){3}$   # 查找行尾的(a.c){3}
/\V(a.c){3}$   # 查找任意位置的(a.c){3}$

默认设置是 magic,vim也推荐大家都使用magic的设置

在正规表达式中使用 /( 和 /) 符号括起正规表达式,即可在后面使用/1 、/2 等变量来访问 /( 和 /) 中的内容。

有了以上内容,我们可以完成一个常用的的替换功能了:

这个是查找if(mRequest[“name”]这样的模式,然后替换成if(mRequest.find("name")

:s/\vif\(mrequest\[(.*)\]/if\(mRequest.find(\$1)/g

上述命令只会替换一行,如果要替换从第5行到底105行,则为:

:5,105s/\vif\(mrequest\[(.*)\]/if\(mRequest.find(\$1)/g

或者全文替换:

:%s/\t/  /gc

c的意思是让你确认,y是确认一个,a是确认所有的。

Vim正则表达式

一、对应《正则表达式30分钟入门教程

deerchao的《正则表达式30分钟入门教程》我读过好几遍,可以说是极好的学习正则表达式的入门文章。我常用的文本编辑器是Vim,具有强大的查找功能。不过,Vim的表示方式和《正则表达式30分钟入门教程》有些不同。这遍文章对应教程,把不同部分列出来,作为备份。
说明:相同的就不列出来了。

序号

入门教程

Vim

备注

1

\b是正则表达式规定的一个特殊代码……代表着单词的开头或结尾,也就是单词的分界处

没有直接对应的。
\<,表示单词的起始;
\>,表示单词的结

要查找单词hi,要用 \

2

+则匹配重复1次或更多次

\{1,} 1 或更多,同 \+

\d+匹配1个或更多连续的数字,Vim用 \d\+ (匹配连续几个数字)

3

? 重复零次或一次

\{0,1}   0 或 1,同 \=

4

\(?0\d{2}[) -]?\d{8}
这个表达式可以匹配几种格式的电话号码

\(\=0\d\{2}[) -]\=\d\{8}

5

如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开

在一个查找模式中,"或" 运算符是 "\|"

6

\b(\w+)\b\s+\1\b
可以用来匹配重复的单词

\<\(\w\+\)\s\+\1\>

7

\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分)

\<\w\+\(ing\)\@=

Vim称为:零宽度匹配前面的匹配原

8

(?<=\bre)\w+\b 会匹配以re开头的单词的后半部分(除了re以外的部分)

\(\

零宽度反向匹配。要求前面的匹配原紧贴在后面的模式之前匹配

9

假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了)
((?<=\d)\d{3})+\b

\(\(\d\)\@<=\d\{3}\)\+\>

10

(?<=\s)\d+(?=\s)匹配以空白符间隔的数字

\(\s\)\@<=\d\+\(\s\)\@=

11

匹配包含后面不是字母u的字母q的单词

\b\w*q(?!u)\w*\b

\<\w*q\(u\)\@!\w*\>

零宽度否匹配,亦即,要求前面的匹配原在当前位置_不_匹配

12

\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字

\d\{3}\(\d\)\@!

13

\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词

\<\(\(\(abc\)\@!\)\w\)\+\>

14

(?

\([a-z]\)\@

零宽度反向否匹配,要求前面的匹配原_不_紧贴在其后的模式之前匹配

15

(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容

\(<\3>\)\@<=.*\(<\/\(\w\+\)>\)\@=

表达式写出来 了,验证可用,但不明白为什么是\3。

二、其它实例

实例1: 密码验证:由且仅由数字、字母(大小写)组成,两者缺一不可,密码不少于6位。
正则表达式: ^\(.*\d\)\@=\(.*[a-z]\)\@=[a-z0-9]\{6,}$

实例2: 十位的数字、字母组合密码,其中包含4位数字和6位字母。
正则表达式: ^\(.*\d.*\d.*\d.*\d.*\)\@=\(.*[a-z].*[a-z].*[a-z].*[a-z].*[a-z].*[a-z].*\)\@=[a-z0-9]\{10}$

注:这两个例子来自《两条与密码验证相关的正则表达式问题》 实例3:把[a]替换为[a]
正则表达式:%s/\(^.*\)/\1<\/A>/g

实例4:把[a 1]替换为[1]

注:[a 1]] 中,a、1之间是tab。
正则表达式:%s/\(^.\{-}\)\t\(.\{-}$\)/\2<\/A>/g
%s/\(^.\{-}\)\t\(.*\)/
\2<\/A>/g

实例五:匹配所有汉字

我无法做到,只能通过迂回的方式来达到。

正则表达式:[^\x00-\x7f]\+

表示非ASCII码的集合,包括汉字。

:%s/\([a-z]\)\ \([\u4e00-\u9fa5].\+\)$/\1\t\2/g

. 匹配任意一个字符

awk中倒数第二列: cat 1-iplist.txt | awk '{ print $(NF-2) }'|wc

\v[\u4e00-\u9fa5]+ " 匹配中文,\v代表very magic,vim7.4支持此方法,但vim8.0在旧的正规表达式引擎中字符值的距离不能超过256,例如设置 re=1 后搜索[\u3000-\u4000],会报错E945。在模式之前加上\%#=2可以解决这个问题,写在匹配模式最前边。

vim8.0匹配中文字符: [^\x00-\xff]

vim的正则表达式(一)

分类: vim 2013-09-04 00:19 1906人阅读 评论(5) 收藏 举报

目录(?)[+]


本文出自   http://blog.csdn.net/shuangde800

------------------------------------------------------------------------------------------------

本文是在学习《使用vi编辑器, Lamb & Robbins编著》时在所记的笔记。

 
本文内容:
模式匹配规则(正则表达式)
元字符
模式匹配举例
本文约定:
$ + 命令 表示在普通的bash的命令行下
:  + 命令 表示在vim的ex(命令)模式, 按"Ctrl"
+ ":" 进入

------------------------------------------------------------------------------------------------

搜索模式的元字符

进行全局替换时,不仅可以使用固定的字符串,还允许是搜索由正则表达式指代的可变的单词模式。
当你指定一个字面的字符串时,搜索可能会找到不想匹配的其他实例。
例如,在文件搜索单词时,单词可以有不同的使用方式。正则表达式有助于在上下文中搜索单词。要注意正则表达式可以与vi的搜索命令/,?以及ex中的:g,:s命令一起使用。
正则表达式由普通字符和许多称为元字符的专用字符结合在一起组成,元字符及其使用方法如下所示。 

元字符 用法
 .(点)
匹配除换行符之外的任何一个单个字符。空格也将作为字符。
例如p.p可以匹配pep,pip和pcp.
  *(星号)
星号前面的一个字符可以出现0次或多次。
例如,bugs*将匹配bugs,bugss或bug。
*可以跟任何元字符。例如,由于.(点)代表任何字符,因此 .* 表示“匹配任意数量的任何字符”。   
:s/End.*/End/  会删除End后面的所有字符
  ^
 当处在正则表达式的第一位时,它要求后面的正则表达式要出现在一行的开始。
例如,^Part可以匹配Parter,Partxx,但是不能匹配HeParter; ^...匹配一行的前三个字符。当^不在正则表达式的开始时,^只代表本身。
  $
  当处于正则表达式的最后一位时,它要求前面的正则表达式要出现在一行的结尾。
  例如,here$可以匹配where, 但是不能匹配whoherehe。当不在结尾时,$就代表它本身。
   \   这是转义字符,可以把后面的元字符看成普通字符。例如\.表示一个普通的字符点, \*表示普通字符星号, \\可以获得真正的反斜杆(\)。
  [ ]    
 匹配方括号中字符的任意一个。 
例如[AB] 将匹配A或B,p[aeiou]t,匹配pat,pet,pit,pot或put。可以通过使用连字符(-)来指定范围。例如,[A-Z]匹配字母A到Z之间的任意一个大写字母。[0-9]将匹配数字0到9之间的任意一个数字。
可以在方括号内包括多个范围,也可以把范围和单独的字符混合在一起。例如[:;A-Za-z()]将匹配四种不同的标点符号和所有的字母。
大部分元字符都将在方括号内失去它们的特殊含义,因此如果想把它们作为普通字符使用,就不需要对它们进行转义。在方括号内仍需要转义的三个元字符是\,-和]。连字符(-)的含义是范围说明符,如果要使用真正的连字符,也可以将其放在放括号内的第一个字符位置。
插入符号(^)只有它在方括号内为第一个字符时才有特殊含义,但是这种情况下其含义与通常^元字符的含义不同。作为方括号的第一个字符,^使它们的含义反过来:将匹配不在方括号里的任何一个字符。例如,[^a-z]将匹配任何不是小写字母的字符。
 和   
 把和之间的模式保存到专门的存储空间(存储缓冲区)中,单一行最多可以保存9个模式。例如,要把this or That改为That or this
:%s/this or That/\2 or \1/   \2和\1是对缓冲区的引用
 \<和\>    在单词的开始(\<)或结尾(\>)匹配字符。单词的开始或结束由标点符号或空格决定。

例如: \<ac将只匹配ac开头的单词, ac\>将匹配以ac结尾的单词
 ~
 匹配上一次搜索中使用的任何正则表达式。
如果搜索过The,那么可以使用/~n来搜索Then。可以把~等价与上次的The,再加上n组合成Then
上面只是一些很基本的正则表达式,除此之外还有很多拓展的正则表达式语法。

元字符在替换串中的使用

当在进行全局替换时,上面的正则表达式之有在命令搜索的部分有特殊含义,在替换串中是按照字符原来的意思来的。
例如,
:%s /hello/$.^/   会把hello替换成$.^,$.^在这里没有特殊含义,不需要用转义(用了也可以)

替换串中的元字符

元字符 用法
 \   转义
 &
用在替换串,它代表与搜索模式想匹配的整个文本,即“重现”搜索串。这在试图避免重复输入文本时很有用。例如,
:%s/hello/&, world/    将会把hello替换成hello, wolrd
:%s/.*/(&)/   将会把所有行用()包含起来
 ~    
 用在替换串中,重复上次的替换串。例如,
上次使用:$ s/his/their/     把his改为their
这次使用:$ s/her/~/         会把her改为their
 \u或\l
 把替换串中的下一个字符分别变成大写或者小写。例如,
:s/yes, sir/\uyes, \usir/g   把yes, sir变成Yes, Sir
\U 或 \L
 将跟在后面的匹配串全部变成大写或小写。例如,
:s/world/\U&/
  把world变成WORLD
以上是基本的正则表达式,还有很多拓展的正则表达式。

更多的替换技巧

  • :s和:s//~/相同,都是重复上次替换
  • 可以把&看作是“同一事情”的意思(与匹配的文本)。
  • &键也可以作为vi命令来执行:&命令(按shift
    + &),即重复上次替换。
  • :~和:&(或shift+&)类似,~是重复上次任何命令中所使用的正则表达式,而不仅仅是替换命令。
  • 除了/字符外,还可以使用除反斜杆,双引号和竖直线(\、"和|) 之外的任何非字母表、非空白字符作为分隔符,在对路径名进行修改时,这点尤其便利: :%s
    ; /user1/tim;/home/time;g  把/user1/tim改为/home/time

模式匹配举例

1. 加入要把一个文件内的所有child替换为children,如果直接用
:%s/child/children/g
可能会有问题,因为把children和Faichild这样的单词中的"child"部分替换为了children,可以用\<和\>来表示“只有该模式是个完整的单词”,
:%s/\<child\>/children/g

搜索单词的常规类

假设你的子函数名以前缀mgi、mgr和mga开头,例如:
mgibox routine,
mgrbox routine,
mgabox routine,
既想保留前缀,又想把box改为square,那么下面两个替换命令都可以完成:
1):g/mg[ira]box/s//mg\1square/g
2):g/mg[ira]box/s/box/square/g
VIM中使用正则匹配中文
摘要: VIM是个很强大的文本编辑器,但是如何使用正则匹配中文似乎会给一些不太了解VIM的人造成小小的麻烦

众所周知,使用JS的正则对中文进行验证时,可以使用:

/[\u4e00-\u9fa5]+/.test('中文')

但是在VIM中再使用这个正则时,则会提示无法找到匹配项

E384: 已查找到文件开头(结尾)仍找不到[\u4e00-\u9fa5]+ 

实际上,VIM的在进行搜索时,有一个'magic'设置,当magic设置为不同的情况时(默认的设置是magic),正则表达式的写法是不同的:

  • magic: 除了`^.*$`之外所有的字符都需要加反斜杠
  • nomagic: 除了`^$`之外所有的字符都需要加反斜杠
  • very magic: 任何字符都不需要加反斜杠
  • very nomagic: 任何字体都需要加反斜杠

可以在正则表达式中指定使用哪种magic

  • \m: magic
  • \M: nomagic
  • \v: very magic
  • \V: very nomagic

例如:

\v[\u4e00-\u9fa5]+ " 查找中文 

所以之前的问题出在哪里也就一目了然了:

[\u4e00-\u9fa5]\+  " 默认为magic, `+`需要加反斜杠 

对于多字节文字,VIM除了`\u`之外,还可以使用如`\U1234`表示小于`0xffffffff`的文字。

 

vim的正则表达式(一)

 
本文内容:
模式匹配规则(正则表达式)
元字符
模式匹配举例
本文约定:
$ + 命令 表示在普通的bash的命令行下
:  + 命令 表示在vim的ex(命令)模式, 按"Ctrl"
+ ":" 进入
------------------------------------------------------------------------------------------------

搜索模式的元字符

进行全局替换时,不仅可以使用固定的字符串,还允许是搜索由正则表达式指代的可变的单词模式。
当你指定一个字面的字符串时,搜索可能会找到不想匹配的其他实例。
例如,在文件搜索单词时,单词可以有不同的使用方式。正则表达式有助于在上下文中搜索单词。要注意正则表达式可以与vi的搜索命令/,?以及ex中的:g,:s命令一起使用。
正则表达式由普通字符和许多称为元字符的专用字符结合在一起组成,元字符及其使用方法如下所示。 
 
元字符 用法
 .(点)
匹配除换行符之外的任何一个单个字符。空格也将作为字符。
例如p.p可以匹配pep,pip和pcp.
  *(星号)
星号前面的一个字符可以出现0次或多次。
例如,bugs*将匹配bugs,bugss或bug。
*可以跟任何元字符。例如,由于.(点)代表任何字符,因此 .* 表示“匹配任意数量的任何字符”。   
:s/End.*/End/  会删除End后面的所有字符
  ^
 当处在正则表达式的第一位时,它要求后面的正则表达式要出现在一行的开始。
例如,^Part可以匹配Parter,Partxx,但是不能匹配HeParter; ^...匹配一行的前三个字符。当^不在正则表达式的开始时,^只代表本身。
  $
  当处于正则表达式的最后一位时,它要求前面的正则表达式要出现在一行的结尾。
  例如,here$可以匹配where, 但是不能匹配whoherehe。当不在结尾时,$就代表它本身。
   \   这是转义字符,可以把后面的元字符看成普通字符。例如\.表示一个普通的字符点, \*表示普通字符星号, \\可以获得真正的反斜杆(\)。
  [ ]    
 匹配方括号中字符的任意一个。 
例如[AB] 将匹配A或B,p[aeiou]t,匹配pat,pet,pit,pot或put。可以通过使用连字符(-)来指定范围。例如,[A-Z]匹配字母A到Z之间的任意一个大写字母。[0-9]将匹配数字0到9之间的任意一个数字。
可以在方括号内包括多个范围,也可以把范围和单独的字符混合在一起。例如[:;A-Za-z()]将匹配四种不同的标点符号和所有的字母。
大部分元字符都将在方括号内失去它们的特殊含义,因此如果想把它们作为普通字符使用,就不需要对它们进行转义。在方括号内仍需要转义的三个元字符是\,-和]。连字符(-)的含义是范围说明符,如果要使用真正的连字符,也可以将其放在放括号内的第一个字符位置。
插入符号(^)只有它在方括号内为第一个字符时才有特殊含义,但是这种情况下其含义与通常^元字符的含义不同。作为方括号的第一个字符,^使它们的含义反过来:将匹配不在方括号里的任何一个字符。例如,[^a-z]将匹配任何不是小写字母的字符。
 和   
 把和之间的模式保存到专门的存储空间(存储缓冲区)中,单一行最多可以保存9个模式。例如,要把this or That改为That or this
:%s/this or That/\2 or \1/   \2和\1是对缓冲区的引用
 \<和\>    在单词的开始(\<)或结尾(\>)匹配字符。单词的开始或结束由标点符号或空格决定。

例如: \<ac将只匹配ac开头的单词, ac\>将匹配以ac结尾的单词
 ~
 匹配上一次搜索中使用的任何正则表达式。
如果搜索过The,那么可以使用/~n来搜索Then。可以把~等价与上次的The,再加上n组合成Then
上面只是一些很基本的正则表达式,除此之外还有很多拓展的正则表达式语法。

元字符在替换串中的使用

当在进行全局替换时,上面的正则表达式之有在命令搜索的部分有特殊含义,在替换串中是按照字符原来的意思来的。
例如,
:%s /hello/$.^/   会把hello替换成$.^,$.^在这里没有特殊含义,不需要用转义(用了也可以)

替换串中的元字符

元字符 用法
 \   转义
 &
用在替换串,它代表与搜索模式想匹配的整个文本,即“重现”搜索串。这在试图避免重复输入文本时很有用。例如,
:%s/hello/&, world/    将会把hello替换成hello, wolrd
:%s/.*/(&)/   将会把所有行用()包含起来
 ~    
 用在替换串中,重复上次的替换串。例如,
上次使用:$ s/his/their/     把his改为their
这次使用:$ s/her/~/         会把her改为their
 \u或\l
 把替换串中的下一个字符分别变成大写或者小写。例如,
:s/yes, sir/\uyes, \usir/g   把yes, sir变成Yes, Sir
\U 或 \L
 将跟在后面的匹配串全部变成大写或小写。例如,
:s/world/\U&/
  把world变成WORLD
以上是基本的正则表达式,还有很多拓展的正则表达式。

更多的替换技巧

  • :s和:s//~/相同,都是重复上次替换
  • 可以把&看作是“同一事情”的意思(与匹配的文本)。
  • &键也可以作为vi命令来执行:&命令(按shift
    + &),即重复上次替换。
  • :~和:&(或shift+&)类似,~是重复上次任何命令中所使用的正则表达式,而不仅仅是替换命令。
  • 除了/字符外,还可以使用除反斜杆,双引号和竖直线(\、"和|) 之外的任何非字母表、非空白字符作为分隔符,在对路径名进行修改时,这点尤其便利: :%s
    ; /user1/tim;/home/time;g  把/user1/tim改为/home/time

模式匹配举例

1. 加入要把一个文件内的所有child替换为children,如果直接用
:%s/child/children/g
可能会有问题,因为把children和Faichild这样的单词中的"child"部分替换为了children,可以用\<和\>来表示“只有该模式是个完整的单词”,
:%s/\<child\>/children/g

搜索单词的常规类

假设你的子函数名以前缀mgi、mgr和mga开头,例如:
mgibox routine,
mgrbox routine,
mgabox routine,
既想保留前缀,又想把box改为square,那么下面两个替换命令都可以完成:
1):g/mg[ira]box/s//mg\1square/g
2):g/mg[ira]box/s/box/square/g
 
 
这里简单的给大家介绍一下Vim的查找替换,众所周知,Vim对正则表达式的支持是非常好的,对于程序员来说在分析大量数据的时候,用到Vim的这个功能无疑是件利器。

首先大家要明白vim正则里面的几个特殊含义:

^ 代表行首

$ 代表行尾

\d 代表数字

\D 代表非数字

[x,y,z]:代表各种条件选择

好的,那我们就出几个常用的题目做一下来试一下吧:

1.将以数字开头的行删除

%s/^\d.*$//igc :把这行置成空

%s/^\d.*$\n//igc :把这行直接删掉,包括换行符一起删掉,(注意是\n,而不是\r\n,因为这是针对linux平台,)下一行会到这一行的位置

2.将数字3或者4或者A开头的行删除

%s/^[3,4,A].*$//igc :把这行设置成空

3.

1 IP 202.114.1.1.23444

2 IP 202.114.1.2.wokao

3 IP 202.114.1.3.woai23444

要求最后变为

202.114.1.1

202.114.1.2

202.114.1.3

按照顺序执行如下即可:

%s/\d.*IP //igc

%s/\.\d*$//igc

%s/\.\D.*$//igc

有效使用vim之正则表达式

任何一个现代编辑器或编程语言,如果不支持正则表达式,则可考虑立刻放弃,因为正则表达式不仅仅只是高效,还有点身份地位象征的意味。

正则表达式指使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。如果用vi而不懂正则表达式,则等于根本不会用。正则表达式是vi处理文本最有力的武器,稍微上点“档次”的编辑器或语言都支持正则表达式。花点时间学习正则表达式是跟普通程序员拉开距离的捷径。

正则表达式至少可以做到以下事情:

  • 文本搜索替换
  • 过滤数据
  • 表单验证
  • 网络爬虫实现

注:正则表达式有很多种实现,各版本之间有些诧异,但基础构成方面都是一样的,学习使用的时候要加以区分。

元字符

可理解为关键字或保留字,这些字符做特殊用途

字符 解释
. 匹配换行符以外的任意字符
^ 匹配字符串的开始位置
$ 匹配字符串的结束位置
* 匹配前面的子表达式零次或多次,等价于{0,}
+ 匹配前面的子表达式一次或多次,等价于{1,}
? 匹配前面的子表达式零次或一次,等价于{0,1}
\ 转义符,将特殊字符进行转义
[] [abc]字符集合,匹配所包含的任意一个字符
  [^abc]负值字符集合,匹配未包含的任意字符
  [a-z] 字符范围,匹配指定范围内的任意字符
() 两个字符一起使用,用于创建一个用于匹配的子串,也叫分组
{} {n}匹配确定的n次
  {n,}至少匹配n次,等价于"*"
  {n,m}最少匹配n次且最多匹配m次(其中n<=m)

还有| 交替匹配,符号两边的任意一项

预设字符

字符 解释
\b 单词边界,同\<
\B 非单词边界,同 \>
\d 数字字符,同 [0-9]
\D 非数字字符,同[^0-9]
\s 空白字符,同 [ \t\n\r\f\v]
\S 非空白字符,同 [^\t\n\r\f\v]
\w 字母数字字符,同 [a-zA-Z0-9_]
\W 非字母数字字符,同 [^a-zA-Z0-9_]
\t Tab,同0x09
\r 回车符,同0x0D
\n 换行符,同0x0A
\f 换页符
\v 垂直制表符,同ox0b
\x 十六进制,例如“x41”匹配“A”
\u Unicode字符。例如,u00A9匹配版权符号

POSIX字符类

字符 解释
[:alnum:] 匹配任意一个字母或数字字符
[:alpha:] 匹配任意一个字母字符(包括大小写字母)
[:blank:] 空格与制表符(横向和纵向)
[:digit:] 匹配任意一个数字字符
[:lower:] 匹配小写字母
[:upper:] 匹配大写字母
[:punct:] 匹配标点符号
[:space:] 匹配一个包括换行符、回车等在内的所有空白符
[:graph:] 匹配任何一个可以看得见的且可以打印的字符
[:xdigit:] 任何一个十六进制数(即:0-9,a-f,A-F)
[:cntrl:] 任何一个控制字符(ASCII字符集中的前32个字符)
[:print:] 任何一个可以打印的字符

常用表达式

数字相关

  • 正整数^[1-9]d*$
  • 负整数 ^-[1-9]d*$
  • 整数 ^-?[1-9]d*$
  • 非负整数(正整数 + 0) ^[1-9]d*|0$
  • 非正整数(负整数 + 0) ^-[1-9]d*|0$
  • 正浮点数 ^[1-9]d*.d*|0.d*[1-9]d*$
  • 负浮点数 ^-([1-9]d*.d*|0.d*[1-9]d*)$
  • 浮点数 ^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$
  • 非负浮点数(正浮点数 + 0) ^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$
  • 非正浮点数(负浮点数 + 0) ^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$

格式检查

  • 匹配中文字符 [u4e00-u9fa5]
  • 限定只能输入中文字符:^[u4e00-u9fa5],{0,}$
  • 匹配Email地址:^w+[-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$
  • 匹配URL地址:^http(s)://([w-]+.)+[w-]+(/[w-./?%&=]*)?$
  • 匹配国内电话号码:^((d{3,4})|d{3,4}-)?d{7,8}$
  • 匹配国内邮政编码:[1-9]d{5}(?!d)
  • 匹配国内身份证号: ^d{15}|d{18}$
  • 匹配首尾空白字符 ^s*|s*$
  • 匹配Email地址 w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*
  • 匹配网址URL [a-zA-z]+://[^s]*
  • 匹配ip地址:d+.d+.d+.d+

RegularExpressionValidator表单验证

  • 只能输入数字:^[0-9]*$
  • 只能输入n位的数字:^d{n}$
  • 只能输入至少n位数字:^d{n,}$
  • 只能输入m-n位的数字:^d{m,n}$
  • 只能输入零和非零开头的数字:^(0|[1-9][0-9]*)$
  • 只能输入有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
  • 只能输入有1-3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
  • 只能输入非零的正整数:^+?[1-9][0-9]*$
  • 只能输入非零的负整数:^-[1-9][0-9]*$
  • 只能输入长度为3的字符:^.{3}$
  • 只能输入由26个英文字母组成的字符串:^[A-Za-z]+$
  • 只能输入由26个大写英文字母组成的字符串:^[A-Z]+$
  • 只能输入由26个小写英文字母组成的字符串:^[a-z]+$
  • 只能输入由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
  • 只能输入由数字、26个英文字母或者下划线组成的字符串:^w+$
  • 匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
  • 验证月数:^(0?[1-9]|1[0-2])$正确格式为:“01”-“09”和“1”“12”
  • 验证天数:^((0?[1-9])|((1|2)[0-9])|30|31)$

在vim中使用正则表达式

基本表达式: [range]s/from/to/[flags]

  • range:搜索范围,如果没有指定范围,则作用于但前行。
:1,10s/from/to/ 表示在第1到第10行(包含第1,第10行)之间搜索替换;
:10s/from/to/ 表示只在第10行搜索替换;
:%s/from/to/ 表示在所有行中搜索替换;
:1,$s/from/to/ 同上。
  • flags 有如下四个选项
c confirm,每次替换前询问;
e error, 不显示错误;
g globle,不询问,整行替换。如果不加g选项,则只替换每行的第一个匹配到的字符串;
i ignore,忽略大小写。

例子

  1. 将foo(a,b,c) 改为foo(b,a,c)
    :%s/foo(\([^,]*\),\([^,]*\),\([^)]*\))/foo(\2,\1,\3)/g
  2. 将abcdef abcedg 都替换为 abc asd
    :%s/abc.*/abc asd/g
  3. 删除以数字开头的行
    %s/^\d.*$//g
  4. 删除以[a,b,c]开头的行
    :%s/^[a|b|c].*$//g
  5. 替换windows换行符
    :%s/<c-v><c-m>//g
  6. 将url替换为html链接
    :s/\(http:\/\/[-a-z\._~\+%\/]\+\)/<a href="\1">\1<\/a>/
  7. 将各行的 id 字符串替换为行号
    id 123
    id 456
    :%s/\<id\>/\=line(".")
  8. 将多个空格替换为1个
    :%s/ */ /g
  9. 删除行尾空格
    :%s/ *$//g
  10. 删除行首空格
    :%s/^ *//g
  11. 删除所有空白行
    :g/^\s*$/d
  12. 删除所有出现有string的行
    :g/string/d
  13. 删除所有不包含string的行
    :v/string/d
  14. 删除所有HTMl标签,保留文本
    :%s#<{FNXX==XXFN}\+>##g
  15. 删除重复行
    :%s/^\(.*\)\n\1$/\1/g
  16. 每行开头加一个空格
    :%s/^/ /g
  17. 修改错误拼写,例如文本中出现了beg,bssg,big都替换成bug
    :%s/b[e|s|i].*g/bug/g
  18. 批量添加注释
    :%s/^/#/每行开头添加#号
    :3,10s/^/#/ 3-10行每行开头添加#号

vim 正则表达式 很强大

毋庸多言,在vim中正则表达式得到了十分广泛的应用。 最常用的 / 和 :s 命令中,正则表达式都是不可或缺的。 下面对vim中的正则表达式的一些难点进行说明。

关于magic

vim中有个magic的设定。设定方法为:

:set magic " 设置magic :set nomagic " 取消magic :h magic " 查看帮助

vim毕竟是个编辑器,正则表达式中包含的大量元字符如果原封不动地引用(像perl 那样), 势必会给不懂正则表达式的人造成麻烦,比如 /foo(1) 命令, 大多数人都用它来查找foo(1)这个字符串, 但如果按照正则表达式来解释,被查找的对象就成了 foo1 了。

于是,vim就规定,正则表达式的元字符必须用反斜杠进行转义才行, 如上面的例子,如果确实要用正则表达式,就应当写成 /foo\(1\) 。 但是,像 . * 这种极其常用的元字符,都加上反斜杠就太麻烦了。 而且,众口难调,有些人喜欢用正则表达式,有些人不喜欢用……

为了解决这个问题,vim设置了 magic 这个东西。简单地说, magic就是设置哪些元字符要加反斜杠哪些不用加的。 简单来说:

magic (\m):除了 $ . * ^ 之外其他元字符都要加反斜杠。nomagic (\M):除了 $ ^ 之外其他元字符都要加反斜杠。

这个设置也可以在正则表达式中通过 \m \M 开关临时切换。 \m 后面的正则表达式会按照 magic 处理,\M 后面的正则表达式按照 nomagic 处理, 而忽略实际的magic设置。

例如:

/\m.* # 查找任意字符串 /\M.* # 查找字符串 .* (点号后面跟个星号)

另外还有更强大的 \v 和 \V。

\v (即 very magic 之意):任何元字符都不用加反斜杠\V (即 very nomagic 之意):任何元字符都必须加反斜杠

例如:

/\v(a.c){3}$ # 查找行尾的abcaccadc /\m(a.c){3}$ # 查找行尾的(abc){3} /\M(a.c){3}$ # 查找行尾的(a.c){3} /\V(a.c){3}$ # 查找任意位置的(a.c){3}$

默认设置是 magic,vim也推荐大家都使用magic的设置,在有特殊需要时,直接通过 \v\m\M\V 即可。

本文下面使用的元字符都是 magic 模式下的。

量词

vim的量词与perl相比一点也不逊色。

vim Perl 意义
* * 0个或多个(匹配优先)
\+ + 1个或多个(匹配优先)
\? 或 \= ? 0个或1个(匹配优先),\?不能在 ? 命令(逆向查找)中使用
\{n,m} {n,m} n个到m个(匹配优先)
\{n,} {n,} 最少n个(匹配优先)
\{,m} {,m} 最多m个(匹配优先)
\{n} {n} 恰好n个
\{-n,m} {n,m}? n个到m个(忽略优先)
\{-} *? 0个或多个(忽略优先)
\{-1,} +? 1个或多个(忽略优先)
\{-,1} ?? 0个或1个(忽略优先)

从上表中可见,vim的忽略优先量词不像perl的 *? +? ?? 那样,而是统一使用 \{- 实现的。 这大概跟忽略优先量词不常用有关吧。

环视和固化分组

vim居然还支持环视和固化分组的功能,强大,赞一个  关于环视的解释请参考Yurii的《精通正则表达式》 一书吧。

vim Perl 意义
\@= (?= 顺序环视
\@! (?! 顺序否定环视
\@<= (?<= 逆序环视
\@<! (?<! 逆序否定环视
\@> (?> 固化分组
\%(atom\) (?: 非捕获型括号

和perl稍有不同的是,vim中的环视和固化分组的模式的位置与perl不同。 例如,查找紧跟在 foo 之后的 bar,perl将模式写在环视的括号内, 而vim将模式写在环视的元字符之前。

# Perl的写法 /(?<=foo)bar/ # vim的写法 /\(foo\)\@<=barvim正则表达式 写道

懒惰模式
\{-n,m} 与\{n,m}一样,尽可能少次数地重复
\{-} 匹配它前面的项一次或0次, 尽可能地少
\| "或"操作符
\& 并列

函数式
:s/替换字符串/\=函数式
在函数式中可以使用 submatch(1)、submatch(2) 等来引用 \1、\2 等的内容,而submatch(0)可以引用匹配的整个内容。

与Perl正则表达式的区别 ?
元字符的区别
Vim语法 Perl语法 含义
\+ + 1-任意个
\? ? 0-1个
\{n,m} {n,m} n-m个
\(和\) (和) 分组

例如:
1,
去掉所有的行尾空格:“:%s/\s\+$//”。“%”表示在整个文件范围内进行替换,“\s”表示空白字符(空格和制表符),“\+”对前面的字符匹
配一次或多次(越多越好),“___FCKpd___0rdquo;匹配行尾(使用“\___FCKpd___0rdquo;表示单纯的
“___FCKpd___0rdquo;字符);被替换的内容为空;由于一行最多只需替换一次,不需要特殊标志。这个还是比较简单
的。(/<Space><Tab>)
2,去掉所有的空白行:“:%s/\(\s*\n\)\+/\r/”。这回多了“
\(”、“\)”、“\n”、“\r”和
“*”。“*”代表对前面的字符(此处为“\s”)匹配零次或多次(越多越好;使用“\*”表示单纯的“*”字符),“\n”代表换行符,“\r”代表回
车符,“\(”和“\)”对表达式进行分组,使其被视作一个不可分割的整体。因此,这个表达式的完整意义是,把连续的换行符(包含换行符前面可能有的连续
空白字符)替换成为一个单个的换行符。唯一很特殊的地方是,在模式中使用的是“\n”,而被替换的内容中却不能使用“\n”,而只能使用“\r”。原因是
历史造成的,详情如果有兴趣的话可以查看“:help NL-used-for-Nul”。
3,去掉所有的“//”注释:“:%s!\
s*//.*!!”。首先可以注意到,这儿分隔符改用了“!”,原因是在模式或字符串部分使用了“/”字符,不换用其他分隔符的话就得在每次使用“/”字
符本身时写成“\/”,上面的命令得写成“:%s/\s*\/\/.*//”,可读性较低。命令本身倒是相当简单,用过正则表达式的人估计都知道“.”匹
配表示除换行符之外的任何字符吧。
4,去掉所有的“/* */”注释:“:%s!\s*/\*\_.\{-}\*/\s*!
!g”。这个略有点复杂了,用到了几个不太常用的 Vim
正则表达式特性。“\_.”匹配包含换行在内的所有字符;“\{-}”表示前一个字符可出现零次或多次,但在整个正则表达式可以匹配成功的前提下,匹配的
字符数越少越好;标志“g”表示一行里可以匹配和替换多次。替换的结果是个空格的目的是保证像“int/* space not necessary
around comments */main()”这样的表达式在替换之后仍然是合法的。

:g/^\s*$/d 删除只有空白的行
:s/\(\w\+\)\s\+\(\w\+\)/\2\t\1 将 data1 data2 修改为 data2 data1
:%s/\(\w\+\), \(\w\+\)/\2 \1/ 将 Doe, John 修改为 John Doe
:%s/\<id\>/\=line(".") 将各行的 id 字符串替换为行号
:%s/\(^\<\w\+\>\)/\=(line(".")-10) .".". submatch(1) 
将每行开头的单词替换为(行号-10).单词的格式,如第11行的word替换成1. word
排序 :/OB/+1,$!sort

vim 复制列, 可以用以下命令:%s/.*/&\|&/g

数据如下:

aaa

bbb

ccc

期望得到如下数据:

aaa|aaa

bbb|bbb

ccc|ccc


一、使用正则表达式的命令

使用正则表达式的命令最常见的就是 / (搜索)命令。其格式如下:

/正则表达式

另一个很有用的命令就是 :s(替换)命令,将第一个//之间的正则表达式替换成第二个//之间的字符串。

:s/正则表达式/替换字符串/选项

在学习正则表达式时可以利用 / 命令来练习

二、元字符

元字符是具有特殊意义的字符。使用元字符可以表达任意字符行首行 尾某几个字符等意义。

元字符一览

元字符 说明
. 匹配任意一个字符
[abc] 匹配方括号中的任意一个字符。可以使用-表示字符范围,
[a-z0-9]匹 配小写字母和阿拉伯数字。
[^abc] 在方括号内开头使用^符号,表示匹配除方括号中字符之外的任意字符。
\d 匹配阿拉伯数字,等同于[0-9]
\D 匹配阿拉伯数字之外的任意字符,等同于[^0-9]
\x 匹配十六进制数字,等同于[0-9A-Fa-f]
\X 匹配十六进制数字之外的任意字符,等同于[^0-9A-Fa-f]
\w 匹配单词字母,等同于[0-9A-Za-z_]
\W 匹配单词字母之外的任意字符,等同于[^0-9A-Za-z_]
\t 匹配<TAB>字符。
\s 匹配空白字符,等同于[ \t]
\S 匹配非空白字符,等同于[^ \t]。,正则表达式的"非",代表不想匹配某个字符。 比如字符串 helloword123,/[^0-9]+/g 可以匹配非数字,即匹配结果为 helloword;

另外,如果要查找字符 *、.、/等,则需要在前面用 \ 符号,表示这不是元字符,而只是普通字符而已。

元字符 说明
\* 匹配 * 字符。
\. 匹配 . 字符。
\/ 匹配 / 字符。
\\ 匹配 \ 字符。
\[ 匹配 [ 字符。

表示数量的元字符

元字符 说明
* 匹配0-任意个
\+ 匹配1-任意个
\? 匹配0-1个
\{n,m} 匹配n-m个
\{n} 匹配n个
\{n,} 匹配n-任意个
\{,m} 匹配0-m个

表示位置的符号

元字符 说明
$ 匹配行尾
^ 匹配行首
\< 匹配单词词首
\> 匹配单词词尾

使用例

/char\s\+[A-Za-z_]\w*;                 " 查找所有以char开头,之后是一个以上的空白,
" 最后是一个标识符和分号
/\d\d:\d\d:\d\d " 查找如 17:37:01 格式的时间字符串
:g/^\s*$/d " 删除只有空白的行
:s/\<four\>/4/g " 将所有的four替换成4,但是fourteen中的four不替换

三、替换变量

在正规表达式中使用 \( 和 \) 符号括起正规表达式,即可在后面使用\1\2 等变量来访问 \( 和 \) 中的内容。

使用例

/\(a\+\)[^a]\+\1                                          " 查找开头和结尾处a的个数相同的字符串,
" 如 aabbbaa,aaacccaaa,但是不匹配 abbbaa
:s/\(http:\/\/[-a-z\._~\+%\/]\+\)/<a href="\1">\1<\/a>/ " 将URL替换为<a href="http://url">http://url</a>的格式
:s/\(\w\+\)\s\+\(\w\+\)/\2\t\1 " 将 data1 data2 修改为 data2 data1

四、函数式

在替换命令 s/// 中可以使用函数表达式来书写替换内容,格式为

:s/替换字符串/\=函数式

在函数式中可以使用 submatch(1)、submatch(2) 等来引用 \1\2 等的内容,而submatch(0)可以引用匹配的整个内容。

使用例

:%s/\<id\>/\=line(".")                              " 将各行的 id 字符串替换为行号
:%s/^\<\w\+\>/\=(line(".")-10) .".". submatch(1) " 将每行开头的单词替换为 (行号-10).单词 的格式,
" 如第11行的 word 替换成 1. word

五、与Perl正则表达式的区别

元字符的区别

Vim语法 Perl语法 含义
\+ + 1-任意个
\? ? 0-1个
\{n,m} {n,m} n-m个
\(和\) (和) 分组

六、vi 正则表达式练习

闲言碎语不要讲…例子说明一切,比如下面这段我需要换成 ubb 标签

vim 命令模式,输入

:%s/.*src=”([^"]*)”[^>]*>/[img]1[/img]/g

替换为

[img ]gu.jpg[ /img]

[img ]os.jpg[ /img]

[img ]hu.jpg[ /img]

[img ]ang.jpg[ /img]

解释如下:

:

命令执行状态

%s

表示查找并替换

%s/a/b/g

a 被查找的字符串(正则匹配);b 要替换成的文字;g 表示全局搜索替换(否则只处理找到的第一个结果)

([^"]*)

表示非引号的字符N个;外面 () 表示后面替换要用(用 1,…,9等引用)

[/img]

/ 需要被 转义

与其它工具正则不一样的地方在于 () 也必须 (),怪不得我老是弄不出来。

相关资料:

via http://net.pku.edu.cn/~yhf/tao_regexps_zh.html

vi 命令 作用

:%s/ */ /g 把一个或者多个空格替换为一个空格。

:%s/ *$// 去掉行尾的所有空格。

:%s/^/ / 在每一行头上加入一个空格。

:%s/^[0-9][0-9]* // 去掉行首的所有数字字符。

:%s/b[aeio]g/bug/g 将所有的bag、beg、big和bog改为bug。

:%s/t([aou])g/h1t/g 将所有tag、tog和tug分别改为hat、hot和hug(注意用group的用法和使用1引用前面被匹配的字符)。

Sed

Sed是Stream EDitor的缩写,是Unix下常用的基于文件和管道的编辑工具,可以在手册中得到关于sed的详细信息。

这里是一些有趣的sed脚本,假定我们正在处理一个叫做price.txt的文件。注意这些编辑并不会改变源文件,sed只是处理源文件的每一行并 把结果显示在标准输出中(当然很容易使用重定向来定制):

sed脚本 描述

sed ’s/^$/d’ price.txt 删除所有空行

sed ’s/^[ ]*$/d’ price.txt 删除所有只包含空格或者制表符的行

sed ’s/”//g’ price.txt 删除所有引号

VIM中正则的非贪婪匹配

<ahref="/celebrity/1049850/">梅莉莎·罗森伯格</a>
变为
梅莉莎·罗森伯格
一开始人工来处理,在visual模式下倒也还快,不过还是觉得可以用正则替换来做,于是先试匹配
<ahref.*>.∗<\/a>
由于贪婪匹配,vim不会匹配到我所要的结果,尝试使用“\?”加到“*”后面,也不奏效
于是google了一番,知道可以在vim中:hnon-greedy查看有关非贪婪匹配的词条,其中提到使用“\{-}”来代替“*”,于是,这么试:
<ahref.\{-}>.\{-}<\/a>
匹配成功,再使用替换命令,一个命令就搞定了之前的工作:
s/<ahref.\{-}>.\{-}<\/a>/\1/g
以上例子说明了磨刀不误砍柴工的道理,同时普及了vim中正则的非贪婪匹配技巧。
附上vim中的正则,以备日后参考。
 
 
 
 

vim中如何贪婪匹配

vim中的匹配实在是不如perl好用,一直想实现非贪婪匹配,今天偶然发现可以用量词匹配来实现,具体可以看:h /\{
\{n,m} Matches n to m of the preceding atom, as many as possible
\{n} Matches n of the preceding atom
\{n,} Matches at least n of the preceding atom, as many as possible
\{,m} Matches 0 to m of the preceding atom, as many as possible
\{} Matches 0 or more of the preceding atom, as many as possible (like *)
\{-n,m} matches n to m of the preceding atom, as few as possible
\{-n} matches n of the preceding atom
\{-n,} matches at least n of the preceding atom, as few as possible
\{-,m} matches 0 to m of the preceding atom, as few as possible
\{-} matches 0 or more of the preceding atom, as few as possible
也就是.\{-}可以实现.*的非贪婪匹配,.\{-1,}可以实现.+的非贪婪匹配。
 
 
 
 

vim 正则匹配竖杠,竖线:

Let's suppose I have a line:

a|b|c

I'd like to run a regex to convert it to:

a\|b\|c

In most regex engines I'm familiar with, something like s%\|%\\|%g should work. If I try this in Vim, I get:

\|a\||\|b\||\|c

As it turns out, I discovered the answer while typing up this question. I'll submit it with my solution, anyway, as I was a bit surprised a search didn't turn up any duplicates.

answer:

vim has its own regex syntax. There is a comparison with PCRE in vim help doc.

except for that, vim has no magic/magic/very magic mode. :h magic to check the table.

by default, vim has magic mode. if you want to make the :s command in your question work, just active the very magic:

:s/\v\|/\\|/g

basically this is a kind of RTFM thing...

坚杠不用转义。

VIM 用正则表达式,非贪婪匹配,匹配竖杠,竖线, 匹配中文,中文正则,倒数第二列, 匹配任意一个字符 :的更多相关文章

  1. 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  2. [转载]Python正则表达式匹配反斜杠'\'问题

    转载自csdnblog:Python正则表达式匹配反斜杠'\'问题 在学习Python正则式的过程中,有一个问题一直困扰我,如何去匹配一个反斜杠(即“\”)? 一.引入 在学习了Python特殊字符和 ...

  3. VIM 用正则表达式

    VIM 用正则表达式 批量替换文本,多行删除,复制,移动 在VIM中 用正则表达式 批量替换文本,多行删除,复制,移动 :n1,n2 m n3     移动n1-n2行(包括n1,n2)到n3行之下: ...

  4. js 正则学习小记之匹配字符串优化篇

    原文:js 正则学习小记之匹配字符串优化篇 昨天在<js 正则学习小记之匹配字符串>谈到 个字符,除了第一个 个,只有 个转义( 个字符),所以 次,只有 次成功.这 次匹配失败,需要回溯 ...

  5. vim下正则表达式的非贪婪匹配

    贪婪模式是: .* 非贪婪模式是: .\{-}

  6. Delphi 正则表达式语法(6): 贪婪匹配与非贪婪匹配

    Delphi 正则表达式语法(6): 贪婪匹配与非贪婪匹配 //贪婪匹配 var   reg: TPerlRegEx; begin   reg := TPerlRegEx.Create(nil);   ...

  7. 正则表达式 整理(\w \s \d 点 贪婪匹配 非贪婪匹配 * + ? {} | [] ^ $ \b 单词边界 分组、re.findall()、re.split()、re.search()、re.match()、re.compile()、re.sub())

    re.findall  匹配到正则表达式的字符,匹配到的每个字符存入一个列表,返回一个匹配到的所有字符列表 一. 匹配单个字符 import re # \w 匹配所有字母.数字.下划线 re.find ...

  8. 廖雪峰Java9正则表达式-2正则表达式进阶-5非贪婪匹配

    1.贪婪匹配 问题:给定一个字符串表示的数字,判断该数字末尾0的个数? "123000": 3个0 "10100": 2个0 "1001": ...

  9. python 正则表达式与JSON-正则表达式匹配数字、非数字、字符、非字符、贪婪模式、非贪婪模式、匹配次数指定等

    1.正则表达式:目的是为了爬虫,是爬虫利器. 正则表达式是用来做字符串匹配的,比如检测是不是电话.是不是email.是不是ip地址之类的 2.JSON:外部数据交流的主流格式. 3.正则表达式的使用 ...

随机推荐

  1. 关于element-ui的弹框问题

    el-dialog获取数据. el-dialog加载到页面中的时候,其实已经加载好了.只是默认隐藏了. 第一次点击的时候弹出,为何拿不到数据?之后再次操作就一点问题都没有了.

  2. hdu5444 乱搞 长春网赛

    可以暴力. #include<iostream> #include<cstring> #define maxn 1100 using namespace std; int a[ ...

  3. poj3261 后缀数组求重复k次可重叠的子串的最长长度

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 13669   Accepted: 6041 Ca ...

  4. iOS 适配iPhoneX上tableHeaderView发生了高度拉伸、UI出现的空白间距

    记录下前阵子遇到的一个问题,草稿箱里记录的有点潦草,讲下大概吧. 异常如下,粉色区域作为tableHeader放上去的(注意不是sectionHeader) header初始化之后一切正常,frame ...

  5. redis :read error on connection

    最近做了一个多人竞拍的小功能  因为以前没做过 所以踩了很多坑用的是 mysql + php + redis 实现的竞拍功能 这里先说一下踩得第二个坑redis  的原因  真是欲哭无泪  解决完一个 ...

  6. CODE FESTIVAL 2017 qual B C - 3 Steps【二分图】

    CODE FESTIVAL 2017 qual B C - 3 Steps 题意:给定一个n个结点m条边的无向图,若两点间走三步可以到,那么两点间可以直接连一条边,已经有边的不能连,问一共最多能连多少 ...

  7. 2019-11-20-dotnet-Blazor-用-C#-控制界面行为

    title author date CreateTime categories dotnet Blazor 用 C# 控制界面行为 lindexi 2019-11-20 18:26:25 +0800 ...

  8. win10 uwp 使用动画修改 Grid column 的宽度

    今天 wurstmitbrot 问如何通过动画修改 Grid 的 column ,虽然 column 是一个依赖属性,可以绑定,但是做出动画还是比较难的. 本文告诉大家如何对 Grid 做动画. 首先 ...

  9. 【MySQL基础】Mysql获得当前日期的所在月的第一天

    Mysql获得当前日期的所在月的第一天 尊重劳动成果,请访问CSDN著者原文链接 http://blog.csdn.net/zixiao217/article/details/51908506 Ste ...

  10. C++第5次作业

    运算符重载 定义 - 运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同行为. 运算符重载规则 - C++运算符除了少数几个,全都可以重载,且只能重载C++已有的运算 ...