DEV Community

SÃĐrgio AraÚjo
SÃĐrgio AraÚjo

Posted on Edited on

Vim: More submatch tricks (and regexes)

How to search and replace in Vim with submatch values

I normally learn a lot on stackoverflow and this comes from it once more

Let's say you have to turn this:

<form>
    <input id="firstname" value="" />
    <input id="lastname" value="" />
    <input id="email" value="" />
</form>
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

into this:

<form>
    <input id="firstname" name="firstname" value="" />
    <input id="lastname" name="lastname" value="" />
    <input id="email" name="email" value="" />
</form>
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

To match only the value after the first equal sign

/id=\v\zs(".{-}")
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

In our above search we have some tricks, the first one is that we only start the very magic after the equal sign, because on vim magic search the equal needs scape. The second trick is using a non-greedy search, for more on this try :help non-greedy. The third trick is using our beloved \zs an unique vim regex feature that says: Beloved vim, use in our substitution only what comes after this point. The oposite is: \ze. For more try: :h \zs. The final trick is using the amper sign & that represents the whole matched pattern.

To apply changes only over a specific paragraph use:

vip  ............... visual inner paragraph
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

And the final command becomes

:'<,'>s//& name=&
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

Notice the double slashes another trick that says to vim: Beloved vim: Don't bother copying the last search to my command line command, just use it as if I have typed it. This trick allows me to separate my search from my substitution command, creating a more concise and easy to read/learn command.

Translating part of a line

some_variable = True #åūŠčŋđįšĒåĪ–äž 
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

So you catch the commenting part with this regex:

    /\v([^#]*&[^"']|^)\zs#.+\ze
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

And you happen to have the program trans installed on your system. You can translate the Chinese part with:

:.s/\v([^#]*&[^"']|^)\zs#.+\ze/\=system('trans -b :en "'. submatch(0) . '"')
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

It is even easier to break down the solution into two pieces:

1 - Search
2 - Substitution

   /\v([^#]*&[^"']|^)\zs#.+\ze
   :.s//\=system('trans -b :en "'. submatch(0) . '"')
ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ” ðŸ”ī Hot News: voyegr/vim more submatch tricks and regexes nd - āļŠāļĢāļļāļ›āļ”āļĢāļēāļĄāđˆāļēāļĨāđˆāļēāļŠāļļāļ”

More reading

I have written another similar post with more stuff, see it here.

Top comments (0)