web-dev-qa-db-fra.com

Expressions régulières floues

Dans mon travail, j'ai utilisé des algorithmes de correspondance approximatifs, tels que la distance de Damerau – Levenshtein, avec d'excellents résultats, pour rendre mon code moins vulnérable aux fautes d'orthographe.

Maintenant, j'ai besoin de faire correspondre des chaînes avec des expressions régulières simples telles que TV Schedule for \d\d (Jan|Feb|Mar|...). Cela signifie que la chaîne TV Schedule for 10 Jan doit renvoyer 0 tandis que T Schedule for 10. Jan doit en renvoyer 2.

Cela pourrait être fait en générant toutes les chaînes de la regex (dans ce cas 100x12) et trouver la meilleure correspondance, mais cela ne semble pas pratique.

Avez-vous des idées sur la manière de procéder efficacement?

44
Thomas Ahle

J'ai trouvé la bibliothèque TRE , qui semble être capable de faire une correspondance exacte des expressions régulières. Exemple: http://hackerboss.com/approximate-regex-matching-in-python/ Il ne prend en charge que l'insertion, la suppression et la substitution. Pas de transposition. Mais je suppose que cela fonctionne bien.

J'ai essayé l'outil d'agendp accompagnant avec l'expression rationnelle sur le fichier suivant:

TV Schedule for 10Jan
TVSchedule for Jan 10
T Schedule for 10 Jan 2010
TV Schedule for 10 March
Tv plan for March

et j'ai

$ agrep -s -E 100 '^TV Schedule for \d\d (Jan|Feb|Mar)$' filename
1:TV Schedule for 10Jan
8:TVSchedule for Jan 10
7:T Schedule for 10 Jan 2010
3:TV Schedule for 10 March
15:Tv plan for March

Merci beaucoup pour toutes vos suggestions.

21
Thomas Ahle

Voir également: The Python regex (version plus récente, oct '14 ) (recherchez "fuzzy" dans le document). 

Si vous n'êtes pas un gars de Python (que je ne suis pas), vous pouvez compiler votre code en C (exe/dll). Ensuite, vous pourrez utiliser votre dll même à partir du bon vieux VB6 (et autres).

Autres bibliothèques à choisir:

  • TRE/aggregp ('classique, bon, ancien et rapide) (recherchez' Agrep performace '), mais vous devez écrire une expression rationnelle compatible POSIX (recherchez' expressions régulières info posix ') Bien entendu, toutes les bibliothèques/exemples utilisant TRE ont cette limitation (recherchez 'hackerboss approximation des expressions rationnelles en python'). Pour des données volumineuses: recherchez 'Une implémentation rapide de l'algorithme d'agendp dans CUDA'.
  • FREJ(Java) - quelques (plusieurs) limitations (par exemple, ne pas regarder devant/regarder derrière)
  • fuzzy-wuzzy (basé sur Python) - intéressant à regarder, pas testé ...

Rechercher aussi pour:

  • 'Comparison_of_regular_expression_engines'
  • 'outils réguliers-expressions.info'

(désolé de ne pas pouvoir poster de vrais liens)

5
Mihail Stanculescu

Je viens d'utiliser le module regex : 'Module d'expression régulière alternatif, pour remplacer re.' Il fournit la familiarité de re mais inclut des options de correspondance floue, ainsi que plusieurs autres améliorations apportées à re.

Pour les fichiers binaires Windows, voir cette ressource .

4
David C

Ici est une ressource sur la question que vous posez. C'est un peu un teaser pour une entreprise. Plus utile pourrait être ce document . J'ai vu une mise en œuvre inspirée par le document qui pouvait effectuer une recherche floue, biaisée pour une langue spéciale (par exemple, l'arabe par rapport à l'anglais), sur un grand jeu de données.

En général, vous ne pourrez pas faire ce que vous avez demandé. Vous pouvez créer une recherche floue en remplaçant des caractères par des classes d'équivalence ou dans une base de données pour des quasi-correspondances définies par la distance de Levenshtein. Essayer d'élargir le (n) DFA derrière une expression rationnelle pour inclure les quasi-matches par la distance deviendrait rapidement d'une complexité impossible.

3
bmargulies

Avez-vous envisagé d'utiliser un lexer ?

En fait, je n'en ai jamais utilisé, je ne peux donc pas vous aider beaucoup, mais ça sonne bien!

1
Paul Creasey

J'ai commencé à implémenter un outil Java appelé prex pour la correspondance approximative des expressions régulières. L'outil détermine dans quelle mesure une chaîne s correspond à une expression régulière r , ie combien d'insertions, de suppressions et de substitutions sur s sont au moins obligatoires (coût minimum) de sorte que la chaîne résultante s 'soit acceptable par r . Si vous êtes intéressé, vous pouvez vérifier le code de https://github.com/julianthome/prex . Je serais très heureux d'avoir des commentaires. Notez que l'approche est encore un peu lente, mais je suis en train d'intégrer des heuristiques pour améliorer ses performances. 

0
Julian