Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Vim中执行条件行拆分的复杂情况_Vim - Fatal编程技术网

在Vim中执行条件行拆分的复杂情况

在Vim中执行条件行拆分的复杂情况,vim,Vim,以下是我正在处理的文本示例: Word1 Word2 ... Word4 / Word5 Word6 Word7 Word8 Word9 Word10 / Word11 Word12 Word13 Word14 Word15 Word16 ... 我想通过拆分包含 斜杠分隔块,以便第一个块(斜杠前面) 获取从第二个块(位于 斜线)使两行中的字数相等,由 如果前一个词比后一个词少的话 换句话说,所需的转换是以线条为目标 由两组单词组成,两组单词之间用空格隔开(包围) 斜杠字符。上的第一组单词(斜

以下是我正在处理的文本示例:

Word1
Word2
...
Word4 / Word5 Word6
Word7
Word8 Word9 Word10 / Word11 Word12 Word13 Word14
Word15
Word16
...
我想通过拆分包含 斜杠分隔块,以便第一个块(斜杠前面) 获取从第二个块(位于 斜线)使两行中的字数相等,由 如果前一个词比后一个词少的话

换句话说,所需的转换是以线条为目标 由两组单词组成,两组单词之间用空格隔开(包围) 斜杠字符。上的第一组单词(斜杠前) 目标行有1到3个单词,但总是少于第二个单词 小组

因此,目标线具有以下结构:

嫀G1›
/
èG2›èG3›

其中èG1›嫀G2›èG3›(即。, 嫀G2›èG3›连接) 构成上述两组单词,用 嫀G2›代表本书中的许多主要词语 后斜杠组与前斜杠组相同,以及 èG3›代表表格中的剩余单词 后斜杠组

此类线路应替换为两条线路,如下所示:

Word1
Word2
...
Word4 Word6
Word5 Word6
Word7
Word8 Word9 Word10 Word14
Word11 Word12 Word13 Word14
Word15
Word16
...
嫀G1›èG3›
嫀G2›èG3›

对于上述示例,预期结果如下所示:

Word1
Word2
...
Word4 Word6
Word5 Word6
Word7
Word8 Word9 Word10 Word14
Word11 Word12 Word13 Word14
Word15
Word16
...

您能帮我在Vim中实现这个转换吗?

对于给定的示例,结果相当于用行上的最后一个单词和换行符替换每个
/
。下面是执行此操作的全局替换命令:

:%s#/ \ze.*\(\<\w\+$\)#\1\r#

:%s#/\ze.*\(\您可以编写一个
函数
展开斜杠

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


之前 之后
可以使用以下命令执行所需的转换:

: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()
    统计该列表中的项目数

    使用字数生成替换命令 并使用
    :执行
    命令运行:

    :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
    原子 模式,其匹配的宽度为零(请参见
    :help/\ze
    )。谢谢 为此,替换命令将替换空字符串 在换行符前面,文本与 子组,从而在 第一个


  • 太谢谢你了,我明天就来试试。你帮了我很多你想象不到的事。几个小时的手工“分类”已经过去了!太谢谢你了!谢谢你的回答,我会尽力理解的…等我有时间的时候time@OlivierPons:从某种意义上说,它是。:-)明天我将添加详细的解释。好主意,可以帮助像我这样的初学者=)@OlivierPons:我已经添加了对建议命令的解释。非常感谢这可能对社区(包括我!)有帮助。您忘记了组
    g1
    g2
    可能包含多个单词(但单词数始终相同)我认为我的命令可以处理
    g1
    g2
    中的多个单词。它所做的只是用最后一个单词替换
    /
    ,因此
    g1
    的精确组合
    
    len(split(getline('.')))
    
    :exe's/\ze\n\%(\s*\w\+\)\{'.len(split(getline('.'))).'}\(.*\)$/\1'