2

I have simple regex to search for lines that only contain alphabetic characters: ^\(\a\)\{1,}$ which works in normal search /^\(\a\)\{1,}$ but not when invoked from my script:

"in .vimrc file:
function DiaryTagBrowser()
  let line = getline('.')
  "if line =~ "^\(\a\)\{1,}$"
  if match(line, "^\(\a\)\{1,}$")
    w! /tmp/vimwiki-tag-list.txt
    enew | set ft=vimwiki | set modifiable
    exe 'read !tagshow.py ' . line
    set nomodifiable
  else
    echo "not on a diaryTag"
  endif
endfunction
command! DiaryTagBrowser : call DiaryTagBrowser()
nnoremap <Enter> :DiaryTagBrowser <Enter>

Testing on a file that looks like:

tagOne
tagTwo
tagThree
not a tag
tagFour

When doing a normal search via / the lines 1, 2, 3, and 5 all match, while line 4 does not match. This is correct/proper/as-expected.

But that same regex in my vimscript doesn't work. When using:

if match(line, "^\(\a\)\{1,}$") the code always runs (the regex also evaluates to true) though it should never run when <Enter> is pressed on line 4.

And when using:

if line =~ "^\(\a\)\{1,}$" the code never runs (regex is always false, always echoing "not on a diaryTag") though it should always run <Enter> is pressed on lines 1-3 and 5.

I've tried many different alterations of the regex expression, but considering the inconsistency I just described the problem does not seem to be with the expression but with how it's invoked.

In this maddening endeavor I've read through: 1 2 3 4 5 6 7 8 9 and several other posts... without finding an explanation of this at all.

What's going on here?

8
  • 6
    See :h expr-quote and :h expr-'. Try :echo "^\(\a\)\{1,}$" and :echo '^\(\a\)\{1,}$'
    – Matt
    Nov 30 '20 at 14:26
  • If I change to single quotes then if line =~ '^\(\a\)\{1,}$' will work... but the same regex used like if match(line, '^\(\a\)\{1,}$') evaluates a true when it should be false and as false when it should be true. Why is that?
    – alec
    Nov 30 '20 at 14:45
  • 2
    match() is neither true nor false.
    – Matt
    Nov 30 '20 at 14:51
  • can you explain? When using match() the logic fails when I expect it to pass and it passes when it should fail.
    – alec
    Nov 30 '20 at 14:54
  • Does match() return the literal string that matches?
    – alec
    Nov 30 '20 at 14:56
2

One of the links referenced put the expression in double quotes ". Using single quotes ' instead fixes the problem with if line =~ '^\(\a\)\{1,}$'.

In order for match() to be used in logic like this it needs to be compared to something like:

if match(line, '^\(\a\)\{1,}$') == 0 since match() returns 0 when it finds a match at the first character or list item (which is the case in this example).

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.