9

I'm trying to create a script for performing fuzzy search inside a buffer. The main idea is to take some input, and insert .\{-} between every pair of characters, e.g. foo becomes f.\{-}o.\{-}o.

This works fairly well, but comes up with a lot of non-ideal matches. I think a fuzzy search should yield the shortest matches first. Consider the following example:

public void put()

Doing a fuzzy search for put (so, p.\{-}u.\{-}t) will match the entire string public void put, but the shorter put within that match would be more useful.

The non-greedy operator is good at finding matches that end earlier, but I need something that can, at the same time, prefer matches that start later. Conceptually, it should be non-greedy in both directions. Is this possible?

  • See also: stackoverflow.com/q/15191291 (no answers for your question though, unfortunately) – Doorknob Feb 4 '15 at 15:06
  • 1
    @Doorknob, no answers, but it does raise a good point: Regex doesn't start searching from the middle of a string. I might have to involve some VimScript to get the job done. I'm exploring the idea of reversing the (long) match, and searching it for the reversed pattern. – tommcdo Feb 4 '15 at 15:38
  • 2
    Tim Pope released vim-haystack today. It sounds similar to what you need. Maybe you can get some inspiration from it or maybe even use it. – tokoyami Feb 5 '15 at 11:38
  • 1
    I want the match to start as late as possible and end as early as possible, while still satisfying the pattern. – tommcdo Feb 7 '15 at 16:29
  • 1
    You should take a look at the so called approximate string matching algorithms, they are more appropriate tools to implement a fuzzy finder than regexps. – toro2k Feb 16 '15 at 16:38
2

There aren't enough examples but I think this does what you want.

.*\zsp.\{-}u.\{-}t

would match put in your example instead of public void put. Basically the .* forces the regex engine to start searching the string backwards, since the .* consumes the whole string first then backtracks, to find the latest match of p.\{-}u.\{-}t

  • I had tried this before (but forgot until now). It's pretty good, but it means that there will only ever be one match per line (the last possible match). I'd still like a line like pouty puppet to yield two matches. – tommcdo Mar 27 '15 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.