vimtricks.wiki Concise Vim tricks, one at a time.

How do I extract regex capture groups from a string in Vimscript?

Answer

matchlist()

Explanation

matchlist({str}, {pattern}) runs a regex match and returns a list of all captured groups, making it the idiomatic way to extract structured data from strings in Vimscript. Index 0 holds the full match; indices 19 hold the contents of each \(…\) group.

How it works

let parts = matchlist('2024-03-15', '\(\d\{4}\)-\(\d\{2}\)-\(\d\{2}\)')
" parts[0] = '2024-03-15'  (full match)
" parts[1] = '2024'        (year)
" parts[2] = '03'          (month)
" parts[3] = '15'          (day)

Returns an empty list [] if the pattern does not match — so always guard:

let m = matchlist(line, pattern)
if !empty(m)
  let year = m[1]
endif

Example

Parse function signatures from Go-style code:

function! ParseFunc(line)
  let m = matchlist(a:line, 'func \(\w\+\)(\(.*\))')
  if empty(m)
    return
  endif
  echom 'Name: ' . m[1] . ', Args: ' . m[2]
endfunction

call ParseFunc('func Connect(host string, port int)')
" Output: Name: Connect, Args: host string, port int

Tips

  • Related: matchstr({str}, {pat}) returns only the full match string; match({str}, {pat}) returns the byte offset.
  • Use \v (very magic) to write patterns with less escaping: matchlist(s, '\v(\d{4})-(\d{2})-(\d{2})')
  • In Neovim Lua: vim.fn.matchlist(str, pattern) works identically.
  • For simple existence checks, prefer match(str, pat) != -1 over !empty(matchlist(...)).

Next

How do I read a single keystroke from the user inside a Vimscript mapping or function?