In VIM, if I do a :echo split('abcd123ef4ghij56k', '\d\+')
, the representation of the list [abcd', 'ef', 'ghij', 'k']
is printed. But I am looking for a behaviour that prints what split() did not return, in this case: ['123', '4', '56']
.
Of course, in a simple example like here, I could change the pattern to \D\+
in order to get what I want. Yet, this is not what I am after because the pattern is an argument in a function and I think I don't know how to opposite the patter开发者_Go百科n.
Here's a function that returns such a list for an expression:
function! MatchMultiplePatterns(txt, re)
let l:result = []
let l:pos = match(a:txt, a:re)
while l:pos != -1
let l:matchedString = matchstr(a:txt, a:re, l:pos)
let l:result += [l:matchedString]
let l:pos = match(a:txt, a:re, l:pos + strlen(l:matchedString))
endwhile
return l:result
endfunction
But I believe this should be possible without a while
-loop and calling match() twice.
Not sure if this is a good solution in the general case, but…
:echo split('abcd123ef4ghij56k', '\d\zs\ze\D\|\D\zs\ze\d') ['abcd', '123', 'ef', '4', 'ghij', '56', 'k'] :echo split('abcd123ef4ghij56k', '\d\@<=\D\@=\|\D\@<=\d\@=') ['abcd', '123', 'ef', '4', 'ghij', '56', 'k']
splits on digit-to-nondigit and nondigit-to-digit boundaries.
I've tried to use negative patterns with no luck (I always have troubles with their logic). Anyway. If you really wish to have something short, we can always have a one-liner based on several calls to substitute that replaces what is in between two occurrences of the pattern by '#', and then finally split on '#'
Otherwise, I'd use match() and matchend() + the_full_string[begin:end] to implement the function you have implemented.
精彩评论