如何使用VIM的Tabular插件进行对齐?

10

以下是我的代码:

john,betty,wally,beth 
walter,george,thomas,john
herbert,bob,petty,mick`

有人知道如何使用VIM的Tabular插件将其对齐为这样:

john,    betty,  wally,  beth
walter,  george, thomas, john
herbert, bob,    petty,  mick

我知道如何在Align插件中完成这个功能,但不知道如何在Tabular中实现。

6个回答

14

我不是Tabularize的专家,下面的内容都是基于我的理解。

Tabularize总是按照正则表达式来分割字段。例如:

abc,d,e
a,b,cde

:Tab /,

这会导致它将每行拆分成以下形式:

|abc|,|d|,|e|
|a|,|b|,|cde|
然后每个字段都用空格填充,以便定界符对齐 - 默认情况下每个字段都会收到额外的空格(最后一个字段除外,我想是这样)。
|abc |, |d |, |e  |
|a   |, |b |, |cde|

结果为:

abc , d , e
a   , b , cde

通过添加标志,您可以控制每个字段的对齐和填充。如果提供的标志不足,则会重复使用它们。因此,要使所有内容以相同方式对齐,例如左对齐并且填充为0,您可以使用单个标志,该标志将为每个字段重复使用。所以:

abc,d,e
a,b,cde

Tab /,/l0 <-- or c0, or r0 or whatever

abc,d,e
a  ,b,cde

我得出的结论是,没有必要使用零宽度字段(例如 :Tab /,\zs),这可能会导致它获取模式后的第一个字符并混乱地切割它。

对于我来说,:Tab /[^,]\+, 没有正常工作,生成了重复的空格:

john,     betty,   wally,  beth
walter,   george,  thomas, john
herbert,  bob,     petty,  mick`
        ^^       ^^

我认为这是因为没有中间字段。这种模式使得一个字段定界符与另一个字段定界符并排而置,像这样:

|john,||betty,||wally,||beth|

默认情况下,生成的包含零的字段(位于分隔符之间)也会使用额外的1个空格进行填充。

|john, | |betty, | |wally, ||beth| <-- for some outrageous reason the las one is cut.

john,  betty,  wally, beth

如何解决此问题?

我的建议是在逗号后面加上一个空格,以便为定界符腾出空间,避免让其紧挨着其他字符。

john,betty,wally,beth 
walter,george,thomas,john
herbert,bob,petty,mick`

:%s/,/, /g

john, betty, wally, beth 
walter, george, thomas, john
herbert, bob, petty, mick`

现在你可以使用空格和零填充来对齐所有内容:

john, betty, wally, beth 
walter, george, thomas, john
herbert, bob, petty, mick`

:Tab / /l0

john,    betty,  wally,  beth
walter,  george, thomas, john
herbert, bob,    petty,  mick`

我希望这能帮助你理解 Tabularize!


非常好的解释!非常感谢。 - Reman
发现一个问题:它在每个空格处对齐,而不仅仅是在逗号后的每个空格处对齐。约翰、贝蒂·戴维斯、沃利、贝丝也将在贝蒂和戴维斯之间对齐。 - Reman
1
尝试使用 :Tabularize /,\zs \+/ - Raimondi
@Remonn,就是这样(感谢@El Isra!)。我没有在文本中包含它,因为我假设不会有额外的空格,但是这个最后一个正则表达式解决了问题。 - sidyll

13
Tabularize /,\zs

请查看:help \zs

由于之前的模式不起作用,请尝试使用以下内容:

Tabularize /[^,]\+,

你的解决方案(我也尝试过)会删除第二列和第三列的前几个字符。 - Reman
好的,我可以重现这个问题,看起来像是一个bug。我已经为此创建了一个工单:https://github.com/godlygeek/tabular/issues/3 - Raimondi
可能并不像是一个漏洞...请查看我的回答 - 这里的文本太多了无法适应。 - sidyll
看起来像是一个 bug,表格不应该从缓冲区中删除文本。 - Raimondi

6

在Raimondi的回答基础上,

:Tabularize /,\zs/l0r1

对我来说更有意义,而且只需要一个命令 :-).

l0r1 表示左对齐,左边填充 0 个空格,右边填充 1 个空格。


1
我正在做类似的事情。我经常需要将逗号分隔的值转换成列:
a, b
a,b,c
a, b, c
a, b, c
ab,cd,ef
ab, cd,ef
ab,cd
ab, cd
john, betty davis, wally, beth walter, george, thomas, john herbert, bob, petty, mick
使用:s/,\s*/, /g准备好添加逗号后的单个空格:
a, b
a, b, c
a, b, c
a, b, c
ab, cd, ef
ab, cd, ef
ab, cd
ab, cd
john, betty davis, wally, beth walter, george, thomas, john herbert, bob, petty, mick
运行:Tab /,\zs \+/10将它们转换为:
a, b
a, b, c
a, b, c
a, b, c
ab, cd, ef
ab, cd, ef
ab, cd
ab, cd
约翰,贝蒂·戴维斯,沃利,贝丝 沃尔特,乔治,托马斯,约翰 赫伯特,鲍勃,佩蒂,米克

现在我只需要弄清如何将它们转换为一个可用的 vmap


1

另一个选择可能是作弊,并将名称也用作分隔符的一部分:

:Tabularize /[a-z]*,/l0l1

该程序寻找任何小写名称和逗号。所有内容都向左对齐,分隔逗号后至少有一个空格。


-1

这个怎么样:

%s/,/,\t/g

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接