这是我的清单:
Word1
Word2
...
Word4 / Word5 Word6
Word7
Word8 Word9 Word10 / Word11 Word12 Word13 Word14
Word15
Word16
...
这就是我想要的:
Word1
Word2
...
Word4 Word6
Word5 Word6
Word7
Word8 Word9 Word10 Word14
Word11 Word12 Word13 Word14
Word15
Word16
...
即。有时在一组1,2或3个单词之间有一个斜杠/
(让我们称之为g1
和g2
),在这些“组”之后,还有更多单词(让我们叫他们g3
)。我想在这两行中分解这一行:第1行= g1 g3
,第2行= g2 g3
您可以在一个宏中执行此操作还是解释如何执行此操作?
答案 0 :(得分:2)
您可以将function
写入expand slash
:
fun! ExpandSlash() range
for i in range(a:firstline, a:lastline)
let ws = split(getline(i))
let idx = index(ws, '/')
if idx==-1
continue
endif
let h= join(ws[ : idx-1])
let m= join(ws[idx+1 : 2*idx])
let t= join(ws[2*idx+1 : ])
call setline(i, h.' '.t.'/'.m.' '.t)
endfor
endfun
:%call ExpandSlash()
:%s@/@\r@
1 2 3 / 4 5 6 7 8
1 2 3 7 8
4 5 6 7 8
答案 1 :(得分:2)
可以使用以下单个命令执行整个操作。
:g~/~s~\s*/\s*~\r~|-|exe's/\ze\n\%(\s*\w\+\)\{'.len(split(getline('.'))).'}\(.*\)$/\1'
此:global
命令选择与模式/
匹配的行(此处为
由~
字符包围),并执行后面的命令
每一行。让我们逐一考虑它们。
具有可选周围空格的斜杠字符,即 分隔当前行上的第一组和第二组单词 (就问题的陈述而言),被换行符取代 字符,
:s~\s*/\s*~\r~
此处,波形符再次用于分隔图案和 替换字符串,这样就不需要转义斜杠了。
替换后,光标位于旁边的行上
/
所在的地方。为了方便下一个命令的措辞,
光标向上移动一行,
:-
-
是表示该行的.-1
范围的缩写
在当前的一个之前(见:help :range
)。
第三组单词,现在位于下一行的末尾,是
被附加到当前的。为了做到这一点,数量
确定第一组中的单词。自当前行
仅包含第一个组,该数字由计算得出
将行的内容分隔为以空格分隔的组
使用split()
函数
len(split(getline('.')))
(getline('.')
将当前行作为字符串split()
返回
将该字符串转换为单词列表,len()
计算该数字
列表中的项目。)
使用该数量的单词,生成替换命令
使用:execute
命令运行
:exe's/\ze\n\%(\s*\w\+\)\{'.len(split(getline('.'))).'}\(.*\)$/\1'
替换具有以下结构,
:s/\ze\n\%(\s*\w\+\)\{
的N
强>}\(.*\)$/\1
其中 N
是放在之前的字数
斜线。
模式匹配当前行的换行符
通过第二行上的 N
字词。一个单词匹配为
一系列一个或多个单词之前的空格序列
字符(请参阅:help /\s
和:help /\w
)。单词模式是
括在\%(
和\)
转义括号(请参阅:help
/\%(
)之间,将其视为\{N}
说明符的单个原子(请参阅
:help /\{
)完全匹配 N
次出现。该
剩下的文本到下一行的末尾被匹配为一个子组
在替换字符串中引用。
由于模式最开始的\ze
原子,因此
match的宽度为零(参见:help /\ze
)。所以,替代
用带有文本的换行符替换该空字符串
由子组匹配,从而插入第三组单词
第一个。
答案 2 :(得分:0)
对于给定的示例,结果相当于将每个/
替换为行上的最后一个单词和换行符\r
。这是一个全局替代命令:
:%s#/ \ze.*\(\<\w\+$\)#\1\r#
说明:
/ \ze
匹配/
结束匹配(\ze
将被替换后没有任何内容).*
匹配任何中间字符\(
启动另一个匹配组\<\w\+$
匹配行尾之前的最后一个字\)
停止匹配组但是,然后您说尾随组g3
可能包含多个单词,这意味着替换操作需要能够计算/
之前和之后的单词数。我担心我不知道该怎么做,但我相信不久有人会跳过你的救援!