views:

53

answers:

3

I need to do it in vim (MacVim) and use it in one line.

z.a2=cross(z.b, z.c)(z.b1, z.c1);

became

z.b2=cross(z.c, z.a)(z.c1, z.a1);

Thank yo

+6  A: 

You could use a dictionary:

:let replacements = {'a': 'b', 'b': 'c', 'c': 'a'}
:s/[abc]r\@!/\=replacements[submatch(0)]/g

The r\@! prevents the c of cross being changed.

Add a % in front of the s if you want to do it on the whole file rather than just the current line. Note that this will change ANY 'a', 'b' or 'c' on the line, including those within words (e.g. the c in cross). To restrict this, you could change the pattern to \<[abc]\>, but that would fail to match where you have a2, so that would suggest: \<\([abc]\)\d*\> (and replace the submatch(0) with submatch(1). If you just want to match where you have the z preceding, this is easy:

:let replacements = {'a': 'b', 'b': 'c', 'c': 'a'}
:s/z\.\zs[abc]/\=replacements[submatch(0)]/g

See:

:help Dictionary
:help :substitute
:help :s\=
:help \@!
:help \zs
:help \(\)
:help \<
Al
The `r\@<!` should just be `r\@!`, and congrats on the silver vim badge!
too much php
Ah yes, good spot: I'll correct it (and thanks for the congrats!)
Al
A: 

How about this one-liner?

%s/\.a/*b*/g | %s/\.b/*c*/g | %s/\.c/*a*/g | %s/\*a\*/.a/g | %s/\*b\*/.b/g | %s/\*c\*/.c/g
darioo
A: 

Search for: z\.(a)(2)=cross\(z\.(b), (z\.c)\)\(z\.b(1), (z\.c1)\);

Replace with: z.$3$2=cross($4, z.$1)($6, z.$1$5);

Vantomex