Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Vim, how to swap 2 non adjacent patterns?

Tags:

regex

vim

I have lines of text, all with the same structure, and would like to make a permutation of 2 elements on all lines:

1257654 some text (which may be long) #Foo
1543098 some other text #Barbar
1238769 whatever #Baz
2456874 something else #Quux

I want to obtain :

#Foo some text (which may be long) 1257654
#Barbar some other text 1543098
#Baz whatever 1238769
#Quux something else 2456874

This is where I am stuck :

:%s/\(\d\{7\}\)\(#.\{-}\)/\2\1/

Where did I go wrong ?

like image 311
ThG Avatar asked Oct 27 '25 05:10

ThG


2 Answers

The problem with your substitution is that you only have two groups instead of three.

Your goal is to swap 1 and 3 around 2:

(1)(2)(3) --> (3)(2)(1)

So you need to have three groups in your pattern:

(1543098)( some other text )(#Barbar)

to be able to do:

(#Barbar)( some other text )(1543098)

This substitution seems to work:

:s/^\(\d\{7\}\)\(.*\)\(#\w*\)/\3\2\1

here is a shorter and prettier version thanks to verymagic:

:s/\v^(\d{7})(.*)(#\w*)/\3\2\1`
like image 185
romainl Avatar answered Oct 29 '25 21:10

romainl


I'd do it

%s/\v^(\d{7})(.{-})\s*(#.*)$/\3\2 \1/

Haven't checked any of the other answers yet

The non-greedy match ({-}) is the key here

like image 29
sehe Avatar answered Oct 29 '25 21:10

sehe