Reman
Reman

Reputation: 8109

How to avoid the 2nd alignment is affected by the 1st alignment?

My text example:

this is my text,this is,this is my text
this, this is my,this is my,this is text

I use Tabular plug-in to align text.

When I want to align at the 1st and 2nd occurrence of a single space '\s' I use these lines:

Tabularize /^\(.\{-}\zs\s\)\{1}/l0
Tabularize /^\(.\{-}\zs\s\)\{2}/l0

But I noted that the 1st alignment add spaces in order to align, but the 2nd alignment is influenced by these extra spaces added and does not the right job.

How can I avoid this?
(I hope I made myself clear)

Edit:

This is what I expected:

this  is   my text,this is,this is my aatext
this, this is my,this is my,this is rtext

This is the outcome:

this       is my text,this is,this is my aatext
this, this is my,this is my,this is rtext

Edit2:

This is my example with >= 2 spaces:

this  is my  text, this is,this  is my aatext
this,  this    is my, this is my,  this is rtext

Adapting the code proposed by Nikita Kouevda in his answer below:

Tabularize /\(^\(\(\S*\s\{2,}\)\{0}\|\(\S*\s\{2,}\)\{2}\)\)\@<=\S*\zs\s/l0

I expected:

this  is my  text, this is,this  is my aatext
this, this    is my, this is my, this is rtext

Outcome:

this  is my  text, this is,this  is my aatext
this, this                                     is my, this is my,  this is rtext

Upvotes: 1

Views: 159

Answers (1)

Nikita Kouevda
Nikita Kouevda

Reputation: 5746

I'm not familiar with Tabular and there might be an option to do this, but I would simply change the second \s to \s\+ in order to match any amount of whitespace:

Tabularize /^\(.\{-}\zs\s\+\)\{2}/l0

Edit: Here's a more proper solution, combining the steps into one:

Tabularize /\(^\(\S*\s\)\{,1}\)\@<=\S*\zs\s/l0

The first part is a lookbehind that matches up to the 0th or 1st space, any non-whitespace characters are then skipped, and the next space is matched (the 1st and 2nd, respectively). This can be generalized to any range; e.g. to align by the 2nd through 5th spaces, use \{1,4}.

Edit: If you need to align by a set of spaces that do not constitute a range in that sense, I would utilize logical ORs in the lookbehind. Unfortunately, this becomes much more clumsy and repetitive. For example, to align by the 1st and 3rd spaces:

Tabularize /\(^\(\(\S*\s\)\{0}\|\(\S*\s\)\{2}\)\)\@<=\S*\zs\s/l0

In order to align each column differently, specify multiple [lcr]# formats. Note that every separating and separated column is counted; e.g. an alignment by 2 spaces results in 5 columns that will be formatted. In order to align by the 1st and 3rd spaces, and to right justify the middle column of text:

Tabularize /\(^\(\(\S*\s\)\{0}\|\(\S*\s\)\{2}\)\)\@<=\S*\zs\s/l0l0r0l0l0

Since the formats cycle if you specify fewer than the number of columns, l0l0r0 would also suffice here, but it's probably a good idea to be explicit.

Upvotes: 1

Related Questions