Как к обратному соответствию строка на языке программирования Vim?

Можно сделать это с AviSynth, с помощью фильтра под названием Deshaker, который записан для VirtualDub, но также и работает с AviSynth.

Это не конкретно Linux, но обе программы упомянули работу вполне хорошо под wine, и определенно Свободны и С открытым исходным кодом в духе и GNU GPL'd. Разработчики просто, оказалось, начинали разрабатывать его земля Windows, и это оказалось слишком трудным порту к *, отклоняют.

Avisynth является языком сценариев медиа. Если Вы довольны сценариями в забое, то AviSnth является потрясающим. Если Вы хотите навести и кликнуть, это не для Вас.

Изображение стоит тысячу слов, таким образом, вот некоторые рисунки (видео на самом деле)..

2
15.12.2012, 11:11
3 ответа

Я озирался, но не нашел никого созданным в функции, которая была похожа на него, сделает то, что Вы хотите.

Вы могли бы найти следующие функции полезными хотя: (изменения, включенные для наложения и неналожения соответствий, запускающихся с начала или конца строки; все они поддерживают мультисимвольные шаблоны с некоторыми ограничениями или ограничениями вокруг использования \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
1
27.01.2020, 22:01

Если я считал вопрос,

echo match('abcabc', '.*\zs[abc]')

ответ: это возвратит начало последнего вхождения шаблона в тексте.

Если Вы хотите другие случаи, которые являются перед последним необходимо будет сократить строку, чтобы продолжить работать 'abcabc'[0:start_of_match+len(matched_string)-1] если Вы хотите принять перекрытия (который не имеет никакого смысла в Вашем случае, поскольку Вы ищете [abc], и нет abc), или 'abcabc'[0:start_of_match-1] иначе.

Править: Извините я пропустил это, это было тем, что делал код Chris Johnsen.

2
27.01.2020, 22:01
  • 1
    , Ваш немного короче. :) –  joeytwiddle 29.07.2014, 04:35
  • 2
    :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
1
27.01.2020, 22:01
  • 1
    я уже задался вопросом в других случаях ли split метод мог демонтировать мудрое символом строки, т.е. без любых разделителей, съедаемых. Я не знал о '\zs' нулевая ширина regex атом. Большой, Спасибо! –  Tim Friske 15.12.2012, 11:26
  • 2
    Но тем не менее, там встроенная функция Vim, которая близко подходит к моему вопросу? –  Tim Friske 15.12.2012, 11:28
  • 3
    @TimFriske: После Вашего редактирования этот ответ не решает его. Это дает последнюю позицию любой из букв, не всех их. Так, в примере это получает последнюю позицию буквы, потому что это - первое без повторного появления после него. Я не знаю о встроенном, но возможно это решение может помочь Вам, потому что это кажется более простым теперь. –  Birei 15.12.2012, 13:07

Теги

Похожие вопросы