2012-02-18

Swapping text segments in Vim

I have a text file with a lot of lines like these:

somebody@abc.com,someoneelse@xyz.com (Invoice 10001234) Recipient Refused
john@company.ca (Invoice 10001235) Recipient Refused
manager@firm.com (Invoice 10001235)

which I would like to turn into lines like these:

(Invoice 10001234) somebody@abc.com,someoneelse@xyz.com  Recipient Refused
(Invoice 10001235) john@company.ca  Recipient Refused
(Invoice 10001235) manager@firm.com

It can be done in Vim with the following command:

:%s#\(.*\)\((Invoice [^)]*)\)\(.*\)#\2 \1\3#

Explanation:

:   command mode
%s  substitute in whole file
#   separator

\(.*\)                1st grouping
\((Invoice [^)]*)\)   2nd grouping
\(.*\)                3rd grouping

In 2nd grouping,
[^)]*  match as many characters as possible as long as it is not )

\1  back reference to 1st grouping

\2  back reference to 2nd grouping
\3  back reference to 3rd grouping


Vim is powerful!