Accueil Faire un système de joker en Python
Post
Annuler

Faire un système de joker en Python

Les expressions régulières, c’est bien… et c’est plutôt simple à intégrer dans un code. Mais quand il s’agit de faire une application qui propose son propre système d’expressions régulières ça fait mal.

C’est un problème sur lequel je me suis penché sur Wapiti afin de permettre aux utilisateurs d’exclure les urls correspondant à certaines expressions.

Mais gérer tous les caractères spéciaux des expressions régulières n’est pas vraiment ce que je cherche étant donné que l’exclusion d’une URL se fera probablement sur un pattern (masque de filtrage) simple et de plus je vois mal quelqu’un tapper des expressions régulières en ligne de commande (sans compter qu’il faudra échapper les caractères spéciaux de bash).

Donc j’ai préféré écrire un système d’expression régulière se limitant au joker (l’astérisque ou wildcard en anglais), comme celui utilisé par Opera pour bloquer les pubs (urlfilter.ini).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env python
import re

def starmatch(regexp,string):
  regexp = re.sub("\*+","*",regexp)
  match = True
  if not regexp.count("*"):
    if regexp == string:
      return True
    else:
      return False
  blocks = regexp.split("*")
  start = ""
  end = ""
  if not regexp.startswith("*"):
    start = blocks[0]
  if not regexp.endswith("*"):
    end = blocks[-1]
  if start != "":
    if string.startswith(start):
      blocks = blocks[1:]
    else:
      return False
  if end:
    if string.endswith(end):
      blocks = blocks[:-1]
    else:
      return False
  blocks = [block for block in blocks if block!=""]
  if not blocks:
    return match
  for block in blocks:
    i = string.find(block)
    if i == -1: return False
    string = string[i+len(block):]
  return match

Quelques tests que j’ai effectués :

1
2
3
4
5
6
7
8
9
10
11
12
regexp=*plop*, string=http://plop : True  
regexp=*plop*, string=plop : True  
regexp=*plop, string=plop8 : False  
regexp=*plop*truc, string=http://ploptruc : True  
regexp=*plop*truc, string=http://ploptruca : False  
regexp=*plop*truc*, string=http://ploptruca : True  
regexp=plop*a*c*truc, string=plopbabctruc : True  
regexp=plop*c*a*truc, string=plopbabctruc : False  
regexp=plop*a*c*, string=plop : False  
regexp=*plop*, string=ploplop : True  
regexp=*plop, string=ploplop : True  
regexp=plop*, string=ploplop : True  

Ca fonctionne :)

Published January 07 2011 at 10:36

Cet article est sous licence CC BY 4.0 par l'auteur.