Home > Blockchain >  Search and replace in 1 step instead of 3 with Vim regex
Search and replace in 1 step instead of 3 with Vim regex

Time:05-07

I have this code that I'd like to transform:

       const createFacebookAdVideoPayload   = {
         const accountId = faker.datatype.uuid();
         const publicLink = faker.internet.url();
         const videoName = faker.lorem.word();

         const facebookToken = undefined;
         const params = null;
         const businessId = faker.datatype.uuid();
       }

I have the habit to use those vim commands for this usually:

  • '<,'>s/const//g
  • '<,'>s/ =/:/g
  • '<,'>s/;/,/g

The end result now being:

        const createFacebookAdVideoPayload = {
          accountId: faker.datatype.uuid(),
          publicLink: faker.internet.url(),
          videoName: faker.lorem.word(),
          facebookToken: undefined,
          params: null,
          businessId: faker.datatype.uuid(),
        };

Isn't there any smart regex possible to do it in one go?

CodePudding user response:

When performing a complex substitution that involves several parts of a line, the usual approach is to use so-called "capture groups". In Vim, it looks like this…

  • Original line:

    Lorem ipsum dolor sit amet.
    
  • Pattern:

    \(Lorem\).*\(dolor\).*\(amet\.\)
    

    We capture what we want to keep and discard the rest.

    • \(Lorem\) matches Lorem as group 1,
    • .* matches any number of any character,
    • \(dolor\) matches dolor as group 2,
    • .* matches any number of any character,
    • \(amet.\) matches amet. as group 3.

    We could also capture what we don't want if that makes things easier or neater.

  • Replacement:

    \1 foo \2 bar \3
    
    • \1 reuses capture group 1,
    • <space>foo<space>,
    • \2 reuses capture group 2,
    • <space>bar<space>,
    • \3 reuses capture group 3.
  • Desired line:

    Lorem foo dolor bar amet.
    

CodePudding user response:

Capture the parts between const, = and ; using \(.*\) and put them back using back-references \n (where n is the group number).

:%s/const\(.*\) =\(.*\);/\1:\2,/

You don't need the global flag /g because there's at most 1 match per line.

I'm not that familiar with vim, but I don't think you need '<,' either, because the above command worked for me without it.

  • Related