I'm trying to determine how many # characters are at the beginning of a line.

In perl, I can so something like this:

$match =~ m/^(#+)[^#])/;
$length = length $1;

Trying to do something similar in vim:

getline(a:lnum) =~ '\v^(#+)[^#]'
let length = strlen \1

I believe the \v allows me to write a regex like perl, correct?

I'm just not sure if I can do capturing like I'm doing here or not.

  • 1
    \v does not mean perl regex; it means very-magic vim regex. In practice you can do all the same things, but the syntaxes differ at points. Check the help for that. Then check the help for match(), substitute(), and submatch() – D. Ben Knoble Apr 27 '19 at 19:31
  • Yeah, I'm familiar with match, but was asking specifically about using capture groups like in perl. – StevieD Apr 27 '19 at 19:35
  • 1
    Have you read :h submatch() ? That should give you enough to experiment and self-answer. – D. Ben Knoble Apr 27 '19 at 19:49
  • Not yet. But I will look into it. Thanks. – StevieD Apr 27 '19 at 20:52

No, VimScript is not like Perl. It's basically a separate programming language and while it look like to support perl like regexes (\v), those are not really perl like, since Vim supports different features for matching (see also :h perl-patterns).

This means, captured groups are basically only valid within a substitute() function (or within a :s command).

To get the number of # at the start of the line, you can however use this:

:echo strlen(matchstr(getline('.'), '^#\+'))

(using '.' for the cursor line).


@ChristanBrabandt typed his answer faster than me, so I won't repeat the information he's already given, or the simpler solution he supplied to your example problem.

However, you suggested in a comment that solving this problem isn't your main goal, and that you actually want to know specifically whether it's possible to use capture groups like in Perl.

I'll therefore add the addendum that Vim does have a close analogue to how you describe Perl's capture groups: the matchlist() function. You can use this to write Vimscript that more closely mirrors your Perl code:

let groups = matchlist(getline(a:lnum), '\v^(#+)[^#]')
let length = empty(groups) ? 0 : len(groups[1])

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.