0

I am trying to run a command on every occurrence of a search match. So, If i have some thing like this where a search match matches only these two anchor tags,

.................. <a src="****" ></a>
......... <a src="****"></a>

I want to run a command that changes it to,

.................. <a class = "bodyclass" src="****" ></a>
......... <a class="bodyclass" src="****"></a>

So, how can I run a command on all the search matches? The only way I can think of is to go to the search match and do a :execute 'normal! Wiclass="bodyclass" ' to insert the class in the tag.

I am not looking for g command here as that operates on the lines and not on the matches directly unless there is a way I can get this functionality with g itself.

Any ideas ?

  • 4
    I've provided an answer that should help. But: Why don't you just use a standard, simple substitute command? E.g. :&s/<a \zs\zesrc="/class="bodyclass" /? See the docs for help on \zs and \ze if you don't know of these from before. – Karl Yngve Lervåg Oct 13 '16 at 7:25
4

You can use the expression register, see :h sub-replace-expression:

:s/search/\=MyFunction(submatch(0))/

The submatch() function can also be used directly inside the function, which would make the syntax even simpler:

:s/search/\=MyFunction()/

To give a concrete example of the latter variant, consider the following Vim function:

function! MyFunction()
  return 'x' . submatch(0) . 'y'
endfunction

And the following text:

this is a test
this is a second test
this is a third test

Now do

:%s/search/\=MyFunction()/

in the text buffer, and the result should be:

this is a xtesty
this is a second xtesty
this is a third xtesty
  • Search and replace would be one way to go. But what if I really want to execute some command on the match. Is there no way to do that? – Durga Swaroop Oct 13 '16 at 7:29
  • @DurgaSwaroop: You should give a concrete example of what you want to do. If you are trying to make the changes you mentioned in your question there is no reason not to use Karl's solution. If you encounter a problem that you can't solve with the substitution you should describe it. – statox Oct 13 '16 at 8:15
  • 1
    @DurgaSwaroop I don't understand why you insist on using a normal command when it is not designed to do what you want. You want to add class="bodyclass" between all <a and src=" that's what the substitution command do see Karl's comment on your question: :%s/<a \zs\zesrc="/class="bodyclass" / does exactly what you want. You should use the tools for what they are made to do. – statox Oct 13 '16 at 8:34
  • 1
    @statox I am not able to think of another usecase for this right now and this is the one I got. The normal command is the only one I can think of for now. I guess I will ask another question when I can think of something else. – Durga Swaroop Oct 13 '16 at 8:40
  • 1
    I think @statox covers most of my own opinions on this matter. I don't see what use case you can have where my solution or something similar won't work well. Using the expression register and the submatch() functions allows you to do most anything with your search matches, including on separate match groups. There is no need to use ex commands on the matches...? – Karl Yngve Lervåg Oct 13 '16 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.