user2485710
user2485710

Reputation: 9801

putting text before the nth occurence in each line in Vim

I have a situation like

something 'text' something 'moretext'

I forgot to add more spacing the first time I created this file and now on each line I should put some whitespace before the 2nd occurence of ' .

Now I can't build a regex for this.

I know that:

The main problem for me is how to build a regex to match the second ' using the {} notation, it's frustrating because I don't where it's supposed to be inserted or if I should use the magic or non-magic regex in vim.

The result I'm looking for

something 'text ' something 'moretext'

Upvotes: 1

Views: 131

Answers (3)

Peter Rincker
Peter Rincker

Reputation: 45087

Yet another way to do it:

:%s/\v%([^']*\zs\ze'){2}/ /

Note: I am using very magic, \v, to reduce amount of escaping.

This approach uses \zs and \ze to set the start and end of the match . The \zs and \ze get set multiple times because of the quantifier, {2} but each occurrence of the group will change the \zs and \ze positions.

For more help see:

:h /\zs
:h /\v

Of course there is always sed, but the trick is getting the quote escaped correctly.

:%!sed -e 's/'\''/ &/2'

Upvotes: 1

romainl
romainl

Reputation: 196476

{2} doesn't mean "the second match", it means "two matches" so it's completely useless for the task.

You could use a substitution like this one or the one in Robin's answer:

:%s/[^']*'[^']*\zs'/ '

Or you could use something like this:

:g/ '[^']*' /norm 2f'i<space>

Upvotes: 2

Robin
Robin

Reputation: 9644

You can use

:%s:\v(^[^']*'[^']*)':\1 ':
  • [^'] means everything except '
  • \1 is a backreference to the first captured group (...)

Basically what your doing here is capturing everything up to the second quote, and replacing the line up to (and including) this quote with what you've captured, a space, and a quote.

Upvotes: 2

Related Questions