Python >> Tutoriel Python >  >> Python Tag >> RegEx

Utilisation correcte des expressions régulières floues (par exemple {e<=2}) en Python

Vérifions cet extrait pour les comptes flous :

>>> pattern_string = 'ATAGGAGAAGATGATGTATA'
>>> query_string = 'ATAGAGCAAGATGATGTATA'
>>> r = regex.compile('(%s){e<=2}' % pattern_string)
>>> r.match(query_string)
<regex.Match object; span=(0, 20), match='ATAGAGCAAGATGATGTATA', fuzzy_counts=(0, 1, 1)>

fuzzy_counts=(0, 1, 1) signifie que dans ce cas, nous n'obtenons aucune substitution, 1 insertion et 1 suppression. Votre filtre fonctionne donc car le nombre total d'erreurs est de 2.

Mais il semble que vous n'ayez besoin de filtrer que par nombre de substitutions, vous pouvez donc modifier la regex :

import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){s<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res

Consultez cet excellent exemple tiré de la documentation :

  • {i<=3} autorise au maximum 3 insertions, mais pas d'autres types
  • {d<=3} autorise au plus 3 suppressions, mais aucun autre type
  • {s<=3} autorisent au plus 3 substitutions, mais pas d'autres types
  • {i<=1,s<=2} autorise au plus 1insertion et au plus 2 substitutions, mais pas de suppressions
  • {e<=3} permet au plus 3 erreurs
  • {1<=e<=3} autoriser au moins 1 et au plus 3 erreurs

  • {i<=2,d<=2,e<=3} autorise au plus 2 insertions, au plus 2 suppressions, au plus 3 erreurs au total, mais pas de substitutions


Votre erreur est de supposer que les "erreurs" sont la même chose que les "substitutions", alors que ce n'est pas le cas.

Le regex La correspondance floue du package comprend trois types d'erreurs :les insertions, les suppressions et les substitutions. Une distance d'erreur spécifiée avec e , comme vous l'avez utilisé, peut être composé de n'importe quelle combinaison de ces erreurs. Et ATAGGAGAAGATGATGTATA peut être édité en ATAGAGCAAGATGATGTATA avec seulement deux opérations de ce type (1 suppression et 1 insertion), comme le montre l'alignement de séquence ci-dessous :

ATAGGAG-AAGATGATGTATA
ATAG-AGCAAGATGATGTATA

existe-t-il un moyen de faire en sorte que cela ne trouve que des chaînes dans la boule de Hamming 2 du modèle donné ?

Oui. Notez que la distance de Hamming est une sorte de distance d'édition qui mesure le nombre minimum de substitutions requis pour éditer une chaîne à une autre de longueur égale. Donc, pour faire correspondre uniquement les chaînes dans le modèle Hamming 2-ball, nous devons indiquer regex pour correspondre à n'importe quoi dans les 2 substitutions , ce que nous pouvons faire en utilisant le s type d'erreur au lieu de e :

import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){s<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res

Est-il possible qu'un échange de lettres soit considéré comme un seul changement ?

Pas dans le regex paquet tel qu'il se présente actuellement. Le terme technique standard pour un "échange" de deux caractères est une "transposition". Les distances d'édition qui incluent des transpositions comme modification possible (par exemple, la distance Dameau-Levenshtein, dans laquelle les modifications peuvent être des insertions, des substitutions, des suppressions ou des transpositions de caractères adjacents) existent et sont utiles pour certaines applications (par exemple, la correction de fautes de frappe). Cependant, au moment de la rédaction, la correspondance floue dans le regex package n'a aucun support pour eux.