如何使用vim查找排列

时间:2014-04-02 20:54:58

标签: string parsing vim sequence

我的问题是解析和更改VIM中的字符串。这有三个方面:

  1. 如果给定一串数字,我怎样才能将每个数字换成另一个数字?

    例如,用3替换1,用1替换2,用2:123替换3变为312

  2. 完成后,如何按数字顺序重新排序字符串中的数字?

    例如,541,203变为145,023

  3. 然后,按数字顺序重新排列字符串?

    例如,234,012,345,123,变成012,123,234,345

  4. 以下是一个示例行:

    025, 056, 125, 235, 256, 257
    

    如您所见,元素中的每个数字都是正确排序的,并且元素也是有序的。但是,我需要按如下方式替换每个数字:

    0 -> 2
    1 -> 3
    2 -> 6
    3 -> 7
    4 -> 0
    5 -> 1
    6 -> 4
    7 -> 5
    

    一旦完成,每个元素的数量将不正常,元素本身也是如此。然后,我需要完成第2步和第3步,以创建一个适当的'新的元素列表。

    我需要为许多不同的线路完成许多替换方案。手动执行此操作需要很长时间,并且容易出错。

    最后,当针对所有行的所有方案完成步骤1-3时,步骤4:删除重复的排列。如果完成步骤2-3,这是微不足道的。

    我如何让VIM为我这样做?甚至可以进行这种文本编辑吗?

3 个答案:

答案 0 :(得分:3)

\=替换部分中使用:s来执行vim表达式。

:%s/\d\+/\=join(sort(split(tr(submatch(0), '01234567', '23670145'), '\zs')), '')/g
:%s/.*/\=join(sort(split(submatch(0), ', ')), ', ')

你也可以使用Tim Pope的Abolish插件代替:Subvert命令代替tr()。例如:%S/{0,1,2,3,4,5,6,7}/{2,3,6,7,0,1,4,5}/g

如需更多帮助,请参阅:

:h :s\=
:h sort(
:h join(
:h split(
:h tr(

答案 1 :(得分:1)

为了帮助您入门,第1步通常是shell命令tr的工作,它在vim中作为函数存在:

:let @q=tr(expand("<cword>"), "0123", "2367")

将在寄存器q中存储光标下的数字的修改版本。但它不是Vim命令,因此您必须编写一个函数来使用它。为了您的目的,Perl或python可能比Vim更合适。

答案 2 :(得分:1)

我同意在vim中做这件事可能比值得更麻烦。这是使用常见命令行工具的完整解决方案:

#!/bin/sh

echo "025, 056, 125, 235, 256, 257" |
tr 01234567 23670145 | awk -F", " '{
    for (i=1; i<=NF; i++) {
        split($i, digits, "")
        n=asort(digits)
        for (x=1; x<=n; x++) {
            printf("%s",digits[x])
        }
        printf("\n")
    }
}' | sort -n |
sed ':a;N;$!ba;s/\n/, /g'