gVim 使用正则表达式在每个匹配模式之前插入序列号
gVim insert serial number before each matched pattern using regex
我在 Windows 上使用 gVim。我有一个 XML 文件,其内容(已提取)如下:
<ExtendedAttributes />
</Activity>
<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="Activity 1">
<Performers>
<Performer>2212646c-2674-4329-9ddc-1f8376e952e1</Performer>
</Performers>
</Activity>
<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="Activity 2">
<Description>This is a dummy description</Description>
<Implementation>
<Task />
我想在每个 activity 的名称前添加一个 ID,即
<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="Activity 1">
会变成
<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="10 Activity 1">
和
<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="Activity 2">
会变成
<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="20 Activity 2">
等等。我试过 \(<Activity Id="[0-9a-f-]*" Name="\)\@<=[A-Za-z ,]\+
可以得到 "Name" 属性的值。但是当我尝试使用 http://vim.wikia.com/wiki/Making_a_list_of_numbers 中提到的命令 :let i=0 | g/.... | let i=i+1
时,我永远无法让它工作。我所能做的就是用序列号替换名称(而我想要 [序列号] [名称] )
任何人都可以解释一下吗?
非常感谢你。
奥利弗
[编辑]
我尝试了以下方法:
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))/g
但它只用数字替换了名字,
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))./g
但我得到 "invalid expression",
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1)).' './g
但我得到 "invalid expression",
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=join((@a+setreg('a',@a+1)),' ',)/g
但我得到 "invalid argument for join()",
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))+/g
但我得到 "invalid expression"。
假设您想要的 ID 是 Activity
后面的数字乘以 10(这是我从您的示例中了解到的),这可以通过以下方式完成:
:%s/Activity \(\d\+\)/\=submatch(1) * 10 . " " . submatch(0)
故障…
对每一行执行替换:
:%s/...
搜索 Activity
,然后搜索 space,然后搜索一个或多个数字,捕获数字:
.../Activity \(\d\+\)/...
在 "sub-replace expression":
中使用捕获的数字和整个匹配
.../\=submatch(1)*10 . " " . submatch(0)
我们用 10、space 和整个匹配连接捕获的数字。
见:help sub-replace
。
我终于找到了分两步完成任务的方法:
1)通过命令插入一个不太可能出现在内容中的静态字符串(例如##%%##%%):
:%s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/##%%##%% /g
2) 用数字序列替换静态字符串:
:let @a=1 | %s/##%%##%%/\=(@a+setreg('a',@a+1))/g
这确实不是一个完美的解决方案。欢迎任何仅 1 步的解决方案。非常感谢你。
这个仅在行尾的 Activity 处发生变化。
首先,我们尝试单独搜索
/Name="\zs[^"]*\ze"
那就问问我们亲爱的vim
let @a=10 | %s//\=(@a+setreg('a', @a+10)) . " " . submatch(0)
我在 Windows 上使用 gVim。我有一个 XML 文件,其内容(已提取)如下:
<ExtendedAttributes />
</Activity>
<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="Activity 1">
<Performers>
<Performer>2212646c-2674-4329-9ddc-1f8376e952e1</Performer>
</Performers>
</Activity>
<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="Activity 2">
<Description>This is a dummy description</Description>
<Implementation>
<Task />
我想在每个 activity 的名称前添加一个 ID,即
<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="Activity 1">
会变成
<Activity Id="ded54c70-1ef4-4aeb-852e-3740882c36ff" Name="10 Activity 1">
和
<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="Activity 2">
会变成
<Activity Id="cf70ec72-4d49-434a-abf3-aa3e8dc000b5" Name="20 Activity 2">
等等。我试过 \(<Activity Id="[0-9a-f-]*" Name="\)\@<=[A-Za-z ,]\+
可以得到 "Name" 属性的值。但是当我尝试使用 http://vim.wikia.com/wiki/Making_a_list_of_numbers 中提到的命令 :let i=0 | g/.... | let i=i+1
时,我永远无法让它工作。我所能做的就是用序列号替换名称(而我想要 [序列号] [名称] )
任何人都可以解释一下吗?
非常感谢你。
奥利弗
[编辑]
我尝试了以下方法:
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))/g
但它只用数字替换了名字,
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))./g
但我得到 "invalid expression",
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1)).' './g
但我得到 "invalid expression",
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=join((@a+setreg('a',@a+1)),' ',)/g
但我得到 "invalid argument for join()",
:let @a=1 | %s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/\=(@a+setreg('a',@a+1))+/g
但我得到 "invalid expression"。
假设您想要的 ID 是 Activity
后面的数字乘以 10(这是我从您的示例中了解到的),这可以通过以下方式完成:
:%s/Activity \(\d\+\)/\=submatch(1) * 10 . " " . submatch(0)
故障…
对每一行执行替换:
:%s/...
搜索
Activity
,然后搜索 space,然后搜索一个或多个数字,捕获数字:.../Activity \(\d\+\)/...
在 "sub-replace expression":
中使用捕获的数字和整个匹配.../\=submatch(1)*10 . " " . submatch(0)
我们用 10、space 和整个匹配连接捕获的数字。
见
:help sub-replace
。
我终于找到了分两步完成任务的方法:
1)通过命令插入一个不太可能出现在内容中的静态字符串(例如##%%##%%):
:%s/\(<Activity Id="[0-9a-f-]*" Name="\)\@<=\([A-Za-z() ,&?;/]\+\)/##%%##%% /g
2) 用数字序列替换静态字符串:
:let @a=1 | %s/##%%##%%/\=(@a+setreg('a',@a+1))/g
这确实不是一个完美的解决方案。欢迎任何仅 1 步的解决方案。非常感谢你。
这个仅在行尾的 Activity 处发生变化。 首先,我们尝试单独搜索
/Name="\zs[^"]*\ze"
那就问问我们亲爱的vim
let @a=10 | %s//\=(@a+setreg('a', @a+10)) . " " . submatch(0)