1

As I see the substitution command e.g.:

:% s/a/b/

puts a into the register "/ but the text that is being replaced is not saved in a register. Now, I would like to replace a with b but keep the result of a in a specific register where I can any moment retrieve it and paste it back at the same position where it was. I mean something like this:

Replace the text:

:% s/^\(.*\)\t\(.*\)/\2/g

Retrieve it from register "z and paste it back where it was:

:% s/^/\=@z/g

I think it should be pretty simple but I couldn't find anything related.

  • So you want the result to be ^<original matched pattern>\2? – padawin Apr 11 at 14:03
  • What does any moment mean? A sample input and output would make your problem much clearer. – dedowsdi Apr 11 at 14:08
  • Apparently I didn't explain it good enough. Vim saves the regex in a register. That's fine but I would also like to have the matched pattern in a register of my choice. – coverflower Apr 11 at 14:42
1

By default, the matched text in a substitution, won't be captured into a register, however it will always be available as atom & in the replace part of your :s command.

Having said that, you can of course store the matched text inside a specific register using the special atom \=.

So for example this:

    function StoreAndReplace(submatch)
        call setreg('z', a:submatch)
        return a:submatch . '_'. getreg('z')
    endfunction

and then running :%s/\w\+/\=StoreAndReplace(submatch(0))/g

will store the matched text in register z and replace the matched text by itsself + the register contents. However this is just a funny way to say:

:%s/\w\+/&_&/g

So one usually just uses the later and not the former way of doing it (especially since the content of the register will be overwritten the next time a replacement is performed).

  • Thanks! I meant something like this: <text11>\t<text12> <text21>\t<text22> ... <textM1>\t<textM2> remove all text before the tab & save it into a register: <text12>\t <text22>\t ... <textM2>\t and then be able to retrieve it from the register any time and place it back exactly where it was. – coverflower Apr 12 at 12:26
  • So you want all replaced matches appended to a register or overwritten each time the replacement is being done? – Christian Brabandt Apr 12 at 13:39
  • Overwrite contents in register. The way @ D. Ben Knoble described was good: clear the register before and then save into it. – coverflower Apr 12 at 14:18
0

You might want &, which is the original matched pattern:

:% s/^\(.*\)\t\(.*\)/&\2/g

Also, when you do a search (or a substitution), your search regex is stored in the register /, you can paste it for example with:

"/p
  • I would like to have the original matched pattern saved in a register of my choice so I can retrieve it any time. – coverflower Apr 11 at 14:37
  • Edited, it should be the missing information you were looking for, the register / – padawin Apr 11 at 14:40
  • But in the register "/ is the regex not the matched pattern, or not? – coverflower Apr 11 at 14:44
  • It is the regex. If your search matches multiple different strings, you couldn't store all the matches at once. – padawin Apr 11 at 14:46
  • So If I understand you correctly there is no way to do it? – coverflower Apr 11 at 14:53
0

Yank all the matching text first, then do your substitute:

  1. Clear a register: qaq
  2. Set a mark at the original point: gg/pattern then mo
  3. Yank text: :g//yank A
  4. Substitute: :%s//replacement/flags

Now paste: 'o"ap

The paste will paste all of the matching text at the location of the first match pre-substitution.

If you want to save each match and the line it came from, I’d write a function to create a buffer-local dictionary (line -> text assuming one match per line, or line -> { column -> text }—dict of dict—for multiple matches anticipated), loop over the matches, grab the text and line number for the dicts, then do the substitution. Then you could write a separate function to "restore" from this dictionary based on line (and column)

  • Thanks! That did almost the trick. There is one minor issue open but I don't need it for the moment, namely inserting the matching text where it was before. I'look into it another time. – coverflower Apr 11 at 17:05
  • @coverflower see edits. Not sure if its helpful – D. Ben Knoble Apr 11 at 17:34
  • Yes, I would also need the lines. The text should be inserted on the left side. I'll try to do it when I find some time. Thanks again! – coverflower Apr 11 at 18:11
0

@Christian Brabandt:

Thanks! I meant something like this:

<text11>\t<text12>
<text21>\t<text22>
...
<textM1>\t<textM2>

remove all text together with the tab & save it into a register:

<text12>\t
<text22>\t
...
<textM2>\t

and then be able to retrieve it from the register any time and place it back exactly where it was. But the example is simple because the removed text starts on the left. What if I wanted to remove text from x to y characters for every line?

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.