From the Vim's help:

echo matchlist('acd', '\v(a)?(b)?(c)?(.*)')
Results in: ['acd', 'a', '', 'c', 'd', '', '', '', '', '']

I understand why the 3rd element is an empty string: 'b' is not present in the string, but what's up with those 5 empty strings at the end?


what's up with those 5 empty strings at the end?

matchlist() always returns the list of 10 items (the matched string and nine submatches - just like \0, \1, ..., \9 in :h sub-replace-special). The last five weren't used, so they are set to empty strings.

  • 2
    You might want to expand this answer to explain why there are only submatches and the relation with the 9 backreferences \1 through \9.
    – filbranden
    Jan 7 '20 at 15:42
  • I wish the documentation of the function were clearer on that. Even after following all the tags it is still not clearly stated about the limit of subgroups, one just have to deduce it.
    – user1602
    Jan 7 '20 at 23:20

As it has been explained, this function will always assume 9 submatches can exist and it will return an entry in the result list for all possible submatch. Hence the 5 extra elements returned.

On a practical note, this means that we cannot call it this way

let [all, a, b, c, end] = matchlist('acd', '\v(a)?(b)?(c)?(.*)') " fails

But we don't have to fill 5 dummy variables either

let [all, a, b, c, end, dummy5, dummy6, dummy7, dummy8, dummy9] = matchlist('acd', '\v(a)?(b)?(c)?(.*)')

Instead, we can use ;. See List unpack chapter just before :h list-modification chapter in Vim documentation -- unfortunately, there is no :h list-unpack entry at this time.

This means the following, with the semicolon, works fine

let [all, a, b, c, end; dummy_tail] = matchlist('acd', '\v(a)?(b)?(c)?(.*)')

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.