Vim
如何反向匹配 Vim 程式語言中的字元串?
我想在字元串中找到
[abc]
集合中 任何字元的最後一個索引,abcabc
但搜尋應該從字元串的末尾開始:" Returns the 0th index but I want the 5th. let a=match('abcabc', '[abc]')
:h functions
我瀏覽了Vim 的“4. 內置函式”reverse
(一個我不明白的限制,因為類似的函式len
被設計成可以處理字元串、數字和列表。為了解決這個問題,我想出了以下功能:
function! s:Rvrs(str) let a=len(a:str) let b=a - 1 let c='' while b >= 0 let c.=a:str[b] let b-=1 endwhile return c endfunction
所以我可以說
let a=match(s:Rvrs('abcabc'), '[abc]')
。
我環顧四周,但沒有找到任何看起來像它會做你想做的事情的內置函式。
不過,您可能會發現以下函式很有用:(包括從字元串開頭或結尾開始的重疊和非重疊匹配的變體;它們都支持多字元模式,但對
\zs
和/或的使用有一些限製或限制\ze
)function! s:AllOverlappableMatches(str, pat) " Restriction: a:pat should not use \ze let indicies = [] let index = 0 let splits = split(a:str, '\ze'.a:pat, 1) for segment in splits if len(segment) == 0 call add(indicies, index) else let index += len(segment) endif endfor return indicies endfunction function! s:AllOverlappableMatchesFromEnd(str, pat) " Restriction: a:pat should not use \ze return reverse(s:AllOverlappableMatches(a:str, a:pat)) endfunction function! s:AllNonoverlappingMatches(str, pat) " If a:pat uses \zs, the returned indicies will be based on that " position. " If a:pst uses \ze, subsequent matches may re-use characters " after \ze that were consumed, but not 'matched' (due to \ze) " in earlier matches. let indicies = [] let start = 0 let next = 0 while next != -1 let next = match(a:str, a:pat, start) if next != -1 call add(indicies, next) let start = matchend(a:str, a:pat, start) endif endwhile return indicies endfunction function! s:AllNonoverlappingMatchesFromEnd(str, pat) " If a:pat uses \zs, the returned indicies will be based on that " position. let str = a:str let indicies = [] let start = len(a:str) - 1 while start >= 0 let next = match(str, '.*\zs' . a:pat, start) if next != -1 call add(indicies, next) let str = str[ : next - 1] endif let start -= 1 endwhile return indicies endfunction echo s:AllOverlappableMatchesFromEnd('abcabc', '[abc]') " -> [5, 4, 3, 2, 1, 0] echo s:AllOverlappableMatchesFromEnd('dabcabc', '[abc]') " -> [6, 5, 4, 3, 2, 1] echo s:AllOverlappableMatchesFromEnd('dab - cabc', '[abc]') " -> [9, 8, 7, 6, 2, 1] echo s:AllOverlappableMatchesFromEnd('dab - cabce', '[abc]') " -> [9, 8, 7, 6, 2, 1] echo s:AllOverlappableMatchesFromEnd('dab - cabc', '[abc]\{2}') " -> [8, 7, 6, 1] echo s:AllOverlappableMatches('dab - cabc', '[abc]\{2}') " -> [1, 6, 7, 8] 0123456789 echo s:AllNonoverlappingMatches('dab - cabc', '[abc]\{2}') " -> [1, 6, 8] 0123456789 echo s:AllNonoverlappingMatchesFromEnd('dab - cabca', '[abc]\{2}') " -> [9, 7, 1] 0123456789A echo s:AllNonoverlappingMatchesFromEnd('ab - cabca', '[abc]\{2}') " -> [8, 6, 0] 0123456789 echo s:AllNonoverlappingMatchesFromEnd('abcabc', '[abc]\{2}') " -> [4, 2, 0] 012345 echo s:AllNonoverlappingMatchesFromEnd(' ab c abcd', '[abc]\{2}') " -> [7, 1] 0123456789 echo s:AllNonoverlappingMatchesFromEnd('abcabc', '[abc]\{2}') " -> [4, 2, 0] 012345 echo s:AllNonoverlappingMatches( 'abcabcabbc', 'abc') " -> [0, 3] 0123456789 echo s:AllNonoverlappingMatchesFromEnd( 'abcdabcabbc', 'abc') " -> [4, 0] 0123456789A " A multi-character, overlappable pattern echo s:AllOverlappableMatchesFromEnd( 'aaaabcaaac', 'aaa') " -> [6, 1, 0] 0123456789
如果我讀了這個問題,
echo match('abcabc', '.*\zs[abc]')
是一個答案:它將返回文本中最後一次出現模式的開頭。
如果您想要在最後一個之前的其他事件,
'abcabc'[0:start_of_match+len(matched_string)-1]
如果您想接受重疊,則必須剪切字元串才能處理(這在您的情況下沒有意義,因為您正在尋找[abc]
,而不是abc
),或者'abcabc'[0:start_of_match-1]
除此以外。編輯:對不起,我錯過了克里斯約翰森的程式碼正在做的事情。