Можно сделать это с AviSynth, с помощью фильтра под названием Deshaker, который записан для VirtualDub, но также и работает с AviSynth.
Это не конкретно Linux, но обе программы упомянули работу вполне хорошо под wine
, и определенно Свободны и С открытым исходным кодом в духе и GNU GPL'd. Разработчики просто, оказалось, начинали разрабатывать его земля Windows, и это оказалось слишком трудным порту к *, отклоняют.
Avisynth является языком сценариев медиа. Если Вы довольны сценариями в забое, то AviSnth является потрясающим. Если Вы хотите навести и кликнуть, это не для Вас.
Изображение стоит тысячу слов, таким образом, вот некоторые рисунки (видео на самом деле)..
Я озирался, но не нашел никого созданным в функции, которая была похожа на него, сделает то, что Вы хотите.
Вы могли бы найти следующие функции полезными хотя: (изменения, включенные для наложения и неналожения соответствий, запускающихся с начала или конца строки; все они поддерживают мультисимвольные шаблоны с некоторыми ограничениями или ограничениями вокруг использования \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]
иначе.
Править: Извините я пропустил это, это было тем, что делал код Chris Johnsen.
:h pattern-atoms
объясняет: \zs Matches at any position, and sets the start of the match there: The next char is the first char of the whole match.
– joeytwiddle
29.07.2014, 04:36
Добавьте следующую функцию к Вашему .vimrc
файл
function! Rvrs( str, chars )
"" 'a:chars' is a string. Convert it to a list.
let l:chars_list = split( a:chars, '\zs' )
"" Process 'str' from the end one character each time.
"" I remove that character from the list if found.
let l:i = len( a:str )
while l:i >= 0 && ! empty( l:chars_list )
let l:i = l:i - 1
if index( l:chars_list, strpart( a:str, l:i, 1 ) ) != -1
let l:dummy = remove( l:chars_list, index( l:chars_list, strpart( a:str, l:i, 1)))
endif
endwhile
"" If the loop go throught all the string means that couldn't find
"" all characters of the list, so return and incorrect code.
"" Otherwise the position where the list got empty.
if i < 0
return -1
else
return l:i
endif
endfunction
и выполните его как:
:echo Rvrs( 'abcabcabbc', 'abc' )
Это уступает:
6
split
метод мог демонтировать мудрое символом строки, т.е. без любых разделителей, съедаемых. Я не знал о '\zs'
нулевая ширина regex атом. Большой, Спасибо!
– Tim Friske
15.12.2012, 11:26