I've been trying to select all characters except the last word (2 groups where 1 group is everything but the last word and the other group is only the last word)
:%s/^.\+\([^\w\+]$\)/\2\1/g
is what I have so far and I've been stuck.
Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It only takes a minute to sign up.
Sign up to join this communityI've been trying to select all characters except the last word (2 groups where 1 group is everything but the last word and the other group is only the last word)
:%s/^.\+\([^\w\+]$\)/\2\1/g
is what I have so far and I've been stuck.
:%s/^\(.\+\)\s\+\(\S\+\)$/\2 \1/
The second pair of parens contains a continuous string of non-whitespace \S\+
(also known as a "WORD") preceding the end of the line.
The first pair of parens gobbles everything else except for some whitespace \s\+
. This requirement of ending before some whitespace prevents it from greedily consuming the final WORD.
This ignores the whitespace between groups 1 and 2 and then reinserts a single space in the substitution. But we could also do three captures if you want to preserve the whitespace exactly (e.g. if it has tabs):
:%s/^\(.\+\)\(\s\+\)\(\S\+\)$/\3\2\1/
Let's make it more readable by using "very magic" mode:
:%s/\v^(.+)(\s+)(\S+)$/\3\2\1/
If a line is indented things get a little ugly. Optionally, we could preserve any indentation thusly:
:%s/\v^(\s*)(.+)(\s+)(\S+)$/\1\4\3\2/
Notes:
\s*
right before $
in the pattern./g
flag is not required as this pattern matches an entire line...only one substitution possible.You've specified that you want to use regular expressions and back-references, but, depending on your precise requirements, it's arguably easier to achieve this without using regular expressions.
:%norm $diw0Pa<Space>
N.B. I've written <Space>
above, as otherwise the space would be invisible: you should enter an actual space character by pressing your space bar once.
This does roughly the same thing as the first :substitute
command in B Layer's answer and, because it just uses normal-mode commands, should be easy to understand for any Vim user:
:%norm
: Run the following series of normal mode commands on every line,$
: Move to end of line; substitute g_
for $
if some of your lines end in whitespace,diw
: Delete inner word; substitute W
for w
if you want to move WORDs,0
: Move to beginning of line; substitute ^
for 0
if you want to preserve indentation,P
: Put the word at the beginning of the line,a<Space>
: Add in a space.If your file also contains blank lines, you can use :global
to only run the :normal
command on non-blank lines:
:g/\S/norm $diw0Pa<Space>
Further improvements are possible if you need more sophisticated handling of whitespace.