Viml matching

From wikinotes

Regex

NOTE:

When using regex you probably want to use 'literal-strings' instead of "strings".

Documentation

vim regex docs http://vimdoc.sourceforge.net/htmldoc/pattern.html#pattern
vim regex 101 http://vimregex.com/
:h magic https://vimhelp.org/pattern.txt.html#%2Fmagic
:h pattern-atoms (ex. ^, \_^, \%$) https://vimhelp.org/pattern.txt.html#%2Fpattern-atoms

Functions

substitution

" equiv to  /s/{2}/{3}/g
substitute("/path/to/project/src/main/java/com/willpittman/package/MyClass.java", '^.*src/\(main\|test\)/java/', "", "g")

match pos

echo match('--abc--abc--', 'abc')     " => 2  match start-pos
echo matchend('--abc--abc--', 'abc')  " => 5  match end-pos
" Getting multiple match positions
echo match('--abc--abc--', 'abc', 1) " => 2 (get 1st match)
echo match('--abc--abc--', 'abc', 2) " => 7 (get 2nd match)
echo match('--abc--abc--', 'abc', 3) " => -1 (get 3rd match -- no matches left)

comparison

if match("string", "^str")  " regex match
'\v...'                     " all non char ranges have special meaning
'\V...'                     " only '\' has special meaning

if "abc" =~ '^ab'         " regex match
if "ABC" =~? '^ab'        " case-insensitive regex
if "ABC" ==? '^ab'        " case-sensitive regex (regardless of :set (no)ignorecase)
if "ABC" ==# '^ab'        " case-insensitive regex (regardless of :set (no)ignorecase)
" .. there are more ..

extract matches

extract matches

call matchstr("  abc", '[a-z]\+')  " 'abc'

extract all matches

With substitute, you can evaluate an expression to perform the substitution.
Take advantage of this to populate a list of matches.

let l:line = "sentence 1. sentence 2! sentence 3?"
let l:submatches = []
call substitute(l:line, '[^\.?\!]\+[\.?\!]*', '\=add(l:submatches, submatch(0))', 'g')
echom l:submatches = ["sentence 1.", "sentence 2!", "sentence 3?"]

Syntax

magic modes

There are 4x variations of magic-ness that you can choose between to simplify your regexes.
The magicness is indicated by prefixing your search with an escape.

/\v${your-regex}
/\m${your-regex}
/\M${your-regex}
/\V${your-regex}

You can use this to make your regexes a bit more readable.

lookahead/lookbehind

" lookahead   (exclude vs include)
syntax 'apple \(orange\)\@!'    " match apple (consume apple), only if orange does not follows it
syntax 'apple \(orange\)\@='    " match apple (consume apple), only if orange follows it


" lookbehind (exclude vs include)
syntax '\(apple\)\@<! orange'   " match orange (consume orange), only if not preceeded by apple
syntax '\(apple\)\@<= orange'   " match orange (consume orange), only if preceeded by apple

apple\zsorange                  " match orange (consume orange), only if preceeded by apple"

lookaround

lookaround allows you to match/ignore strings. They do not become a part of the resulting match.

  • {1}\zs{2} match {2} is preceeded by {1}. {1} is not part of the match
  • {1}\ze{2} match {1} is followed by {2}. {2} is not part of the match
%s/myFunction(\zs.*\ze)/foo/

See https://vi.stackexchange.com/questions/3036/is-lookaround-possible-in-vims-regex-system wed by {2}. {2} is not part of the match

%s/myFunction(\zs.*\ze)/foo/

See https://vi.stackexchange.com/questions/3036/is-lookaround-possible-in-vims-regex-system

Repeated Characters

A\{2}    " 2 repeats of preceeding character
A\{1,3}  " 1-3 repeats of preceeding character

vim matches are non-greedy by default. You can make them greedy

.\{-}    " greedy match of any character

Pattern Atoms

Pattern atoms are all of the character-combinations given special significance within a match.
For a full list, see :h pattern-atoms

\_.     " like '.', but also matches '\r'
\%$     " matches end of file