在替换和全局命令中, 某些元字符(metacharacters)在查找表达式和替换表达式中的含义是不同的。
例如以下命令,查找部分中的“.”因为有特殊意义,所有需要进行转义;而替换部分中的“.”和“$”则会被视为普通文本。
:%s/1. Start/2. Next, start with $100/
1. Start --------> 2. Next, start with $100
例如以下命令,会将“A”或“B”或“C”,分别替换为“[abc]”。也就是说,“[]”在替换部分也会被视为普通文本。
:%s/[ABC]/[abc]/g
ABC --------> [abc][abc][abc]
替换表达式中的元字符(Metacharacters)
使用元字符交换文本位置
使用以下命令,可以交换以逗号分隔的列:
:%s/([^,]*),([^,]*),(.*)/2,1,3/
查找表达式包括:
- ([^,]*),匹配除逗号之外的所有字符,即将第一列的内容捕获为组1;
- ([^,]*),匹配除逗号之外的所有字符,即将第二列的内容捕获为组2;
- (.*),匹配剩余的所有字符,捕获为组3;
替换表达式包括:
- 2,1,3,按照组2组1组3的顺序恢复各组的内容,即交换第二列与第一例的次序。
请注意,作为分隔符的逗号,在查找和替换部分均被视为普通文本。
假设需要将以下记录中的Name字段,转换为Firstname Lastname的形式:
Name: McFly, Susan S.; Areas: Graphics; Phone: 999-3333
可以使用以下命令,将逗号之前的Lastnmae捕获至组1,将分号之前的Firtname捕获至组2,然后再按照从组2到组1的顺序进行替换:
:%s/: ([^,]*), ([^;]*);/: 2 1;/
Name: Susan S. McFly; Areas: Graphics; Phone: 999-3333
使用以下全局命令,则可以将替换操作限制在以“Name:”开头的行:
:g/^Name/s/: *([^,]*), ([^;]*);/: 2 1;/
使用元字符转换大小写
使用以下命令,将单词首字母转换为大写:
:%s/<(.)([^[:space:][:punct:]]*)>/u12/g
查找表达式包括:
- <,匹配单词开头;
- (.),匹配单词首字母,捕获为组1;
- ([^[:space:][:punct:]]*),匹配除空格和标点符号之外的字符串,即将单词首字母之外的其余部分捕获为组2;
- >,匹配单词末尾;
替换表达式包括:
- u,将下一个字符转换为大写;
- 1,恢复捕获组1(即单词首字母)
- 2,恢复捕获组2(即单词剩余部分)
使用以下命令,可以将匹配文本全部转换为大写:
:%s/Fortran/U&/
fortran --------> FORTRAN
使用元字符进行精确替换
假设以下代码中rotine的名称以“test”为前缀,以“box”为后缀,而黄色高亮的中间部分则是可变的:
如果希望将后缀替换为“block”,那么可以将可变的字母作为捕获组进行替换:
:g/test([abc])box/s//test1block/g
假设需要将代码中“?dep=01”替换为:
{{path('index',{dep:01})}}
也就是说,只替换表达式的字符部分,但保留数字部分不变。可以使用(dd)捕获两位数字部分,然后在替换时使用1来恢复数字:
:%s/?dep=(dd)/{{path('index',{dep:1})}}/g