Viml matching: Difference between revisions

From wikinotes
 
(9 intermediate revisions by the same user not shown)
Line 13: Line 13:
|-
|-
| <code>:h magic</code> || https://vimhelp.org/pattern.txt.html#%2Fmagic
| <code>:h magic</code> || https://vimhelp.org/pattern.txt.html#%2Fmagic
|-
| <code>:h pattern-atoms</code> (ex. <code>^, \_^, \%$</code>) || https://vimhelp.org/pattern.txt.html#%2Fpattern-atoms
|-
|-
|}
|}
Line 56: Line 58:
</source>
</source>
</blockquote>
</blockquote>
=== extract matches ===
<blockquote>
'''extract matches'''<br>
<syntaxhighlight lang="vim">
call matchstr("  abc", '[a-z]\+')  " 'abc'
</syntaxhighlight>
'''extract all matches'''<br><br>
With substitute, you can evaluate an expression to perform the substitution.<br>
Take advantage of this to populate a list of matches.
<syntaxhighlight lang="vim">
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?"]
</syntaxhighlight>
</blockquote><!-- extract matches -->
</blockquote><!-- Functions -->
</blockquote><!-- Functions -->


Line 86: Line 106:
syntax '\(apple\)\@<! orange'  " match orange (consume orange), only if not preceeded by apple
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
syntax '\(apple\)\@<= orange'  " match orange (consume orange), only if preceeded by apple
apple\zsorange                  " match orange (consume orange), only if preceeded by apple"
</syntaxhighlight>
</syntaxhighlight>
</blockquote>
</blockquote>
Line 108: Line 130:


See https://vi.stackexchange.com/questions/3036/is-lookaround-possible-in-vims-regex-system
See https://vi.stackexchange.com/questions/3036/is-lookaround-possible-in-vims-regex-system
</blockquote>
</blockquote><!-- Lookaround -->
 
=== Repeated Characters ===
<blockquote>
<syntaxhighlight lang="vim">
A\{2}    " 2 repeats of preceeding character
A\{1,3}  " 1-3 repeats of preceeding character
</syntaxhighlight>
 
vim matches are non-greedy by default. You can make them greedy
<syntaxhighlight lang="vim">
.\{-}    " greedy match of any character
</syntaxhighlight>
</blockquote><!-- Repeated Characters -->
 
=== Pattern Atoms ===
<blockquote>
Pattern atoms are all of the character-combinations given special significance within a match.<br>
For a full list, see <code>:h pattern-atoms</code>
 
<syntaxhighlight lang="vim">
\_.    " like '.', but also matches '\r'
\%$    " matches end of file
</syntaxhighlight>
</blockquote><!-- any char, including newline -->
</blockquote><!-- Regex -->
</blockquote><!-- Regex -->
</blockquote><!-- Syntax -->
</blockquote><!-- Syntax -->

Latest revision as of 17:45, 7 January 2024

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