15

I know that I can yank all matched lines into register A like this:

:g/regex/y/A

But I can't seem to figure out how to yank match regex groups into register A:

:g/\(regex\)/\1y A
(E10: \ should be followed by /, ? or &)
ekad
  • 14,436
  • 26
  • 44
  • 46
user2506293
  • 805
  • 1
  • 7
  • 13

4 Answers4

19

You can do this with a substitute command.

:%s/regex/\=setreg('A', submatch(0))/n

This will append register a to whatever the regex matched. The n flag will run the command in a sandbox so nothing will actually get replaced but the side effects of the statement will happen.

You probably want to empty the register first with

:let @a=''
FDinoff
  • 30,689
  • 5
  • 75
  • 96
  • 1
    Wouldn't using a capital letter register in the `setreg('A', submatch(0))` be easier? – Peter Rincker May 17 '14 at 23:22
  • @PeterRincker Yes yes it would. I didn't realize it would accept capital letter (I also didn't test it...) – FDinoff May 17 '14 at 23:24
  • 4
    The nice part about using the capital letter version is you can use `setreg()`'s third parameter to make it linewsise if you want. `%s/foo/\=setreg('A', submatch(0), 'V')/n` – Peter Rincker May 17 '14 at 23:38
  • 3
    A quicker way to clear register `a` is with the Normal mode command `qaq`. – tommcdo May 26 '14 at 16:16
  • @PeterRincker What if I want to put two matches into two different registers? http://vi.stackexchange.com/q/4356/1788 – Lerner Zhang Aug 16 '15 at 09:46
  • Has this been tested? I can't seem to get it working. Maybe the `/n` turns off the replace part altogether? I'm not sure why it won't work for me... I can't even set `a` to an explicit string when using `/n`. – Miles Jul 30 '17 at 23:40
  • @Miles it was working when I wrote it. Probably best to post a new question if you are having problems. – FDinoff Jul 31 '17 at 02:23
  • @Miles working well for me, especially with Peter's suggestion to use the third parameter in `setreg` so that your matches end up newline-separated. – anton.burger Aug 10 '17 at 09:49
  • 1
    It's a bit hacky, but if you want a newline separator between each match: `:%s//\=setreg('A', submatch(0)) || setreg('A', "\n")/n` – Mateen Ulhaq Nov 20 '18 at 22:04
  • @MateenUlhaq could you lend some wisdom to a vim noob and tell me the best way to make a command out of that? What I would die for is a way that I can still use `/` to do the search so I can see a preview of the match and then somehow pipe that to something that would load it into my register. Like `/\vsome_regex | ` There is nothing more frustrating than seeing all my nice matching regexes on each line, all highlighted, and then trying to remember this incantation to get it into the blasted register – ohhh Mar 14 '19 at 09:43
0

If you just want to grab one part of the match, you can work with \zs and \ze. You need capture groups only for multiple parts, or reordering.

My ExtractMatches plugin provides (among others) a convenient :YankMatches command that also supports replacements:

:[range]YankMatches[!] /{pattern}/{replacement}/[x]
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
0

You can also yank all matched line between two sessions to pointed register.

By way of example:

:11,21s/regex/\=setreg('A', submatch(0))/n

Matches regrex group from line 11 to line 21 rather than the whole file.

:/^ab/,/^cd/s/regex/\=setreg('A', submatch(0))/n

Matches regrex group from the line that stards with ab to line with cd.

More about session: http://vimregex.com/

Lerner Zhang
  • 6,184
  • 2
  • 49
  • 66
0

Wouldn't work for me with the /n flag - got nothing in the register - and without it vim did the substitute on the line.

Ended up with:

:g/pat1/s~pat2\\(regex\\)pat3~\=submatch(0).setreg('a',submatch(1))~

which seemed to do what I wanted.

David Buck
  • 3,752
  • 35
  • 31
  • 35