Regex qui préfère les matchs plus courts dans un match? (C'est plus impliqué que non gourmand)

9

J'essaie de créer un script pour effectuer une recherche floue dans un tampon. L'idée principale est de prendre une entrée et d'insérer .\{-}entre chaque paire de caractères, par exemple foodevient f.\{-}o.\{-}o.

Cela fonctionne assez bien, mais propose de nombreuses correspondances non idéales. Je pense qu'une recherche floue devrait donner les correspondances les plus courtes en premier. Prenons l'exemple suivant:

public void put()

Faire une recherche floue pour put(donc p.\{-}u.\{-}t) correspondra à la chaîne entière public void put, mais le plus court putdans cette correspondance serait plus utile.

L'opérateur non gourmand est bon pour trouver des correspondances qui se terminent plus tôt, mais j'ai besoin de quelque chose qui puisse, en même temps, préférer des correspondances qui commencent plus tard. Conceptuellement, il devrait être non gourmand dans les deux sens. Est-ce possible?

tommcdo
la source
Voir aussi: stackoverflow.com/q/15191291 (malheureusement pas de réponse à votre question)
Bouton de porte
1
@ Doorknob, pas de réponse, mais cela soulève un bon point: Regex ne commence pas la recherche au milieu d'une chaîne. Je devrai peut-être impliquer du VimScript pour faire le travail. J'explore l'idée d'inverser la (longue) correspondance et de la rechercher pour le motif inversé.
tommcdo
2
Tim Pope a publié vim-haystack aujourd'hui. Cela ressemble à ce dont vous avez besoin. Peut-être pouvez-vous vous en inspirer ou peut-être même l'utiliser.
tokoyami
1
Je veux que le match commence le plus tard possible et se termine le plus tôt possible, tout en satisfaisant le schéma.
tommcdo
1
Vous devriez jeter un œil aux soi-disant algorithmes d'appariement de chaînes approximatifs , ce sont des outils plus appropriés pour implémenter un chercheur flou que des regexps.
toro2k

Réponses:

2

Il n'y a pas assez d'exemples mais je pense que cela fait ce que vous voulez.

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

correspondrait putdans votre exemple au lieu de public void put. Fondamentalement, cela .*force le moteur d'expression régulière à commencer à rechercher la chaîne en arrière, car le .*consomme d'abord la chaîne entière, puis revient en arrière, pour trouver la dernière correspondance dep.\{-}u.\{-}t

FDinoff
la source
J'avais déjà essayé cela (mais j'ai oublié jusqu'à présent). C'est plutôt bien, mais cela signifie qu'il n'y aura jamais qu'un seul match par ligne (le dernier match possible). J'aimerais toujours qu'une ligne pouty puppetdonne deux matchs.
tommcdo