ATOUTFOX
COMMUNAUTÉ FRANCOPHONE DES PROFESSIONNELS FOXPRO
Visual FoxPro : le développement durable

RegExPatternHelper class   



L'auteur

Gregory Adam
Belgique Belgique
Membre Actif (personne physique)
# 0000001121
enregistré le 04/06/2006

Fiche personnelle


Note des membres
19,5/20
2 votes


Contributions > 01 - PRG : Programmation > Maths - Matrices - Algos

RegExPatternHelper class
# 0000000695
ajouté le 23/05/2009 16:33:17 et modifié le 24/05/2009
consulté 5774 fois
Niveau débutant


Le téléchargement des pièces jointes est limité aux membres
Veuillez vous identifier ou vous inscrire si vous n'avez pas encore de compte ...
Description

RegexPatternHelper

Le but de cette classe est de faciliter la création de Patterns

Il est assez difficile d’écrire un pattern qui accepte une date.  Si on ajoute (1) qu’on accepte les années en 2 et en 4 positions, (2) que le séparateur peut être / ou -, (3) qu’on va valider au maximum les dates, cela devient assez difficile

Mais si on pouvait définir des pièces qu’on va réutiliser, cela devient un peu plus facile

Il faut aussi télécharger le Topological Sort :

http://www.atoutfox.com/articles.asp?ACTION=FCONSULTER&ID=0000000645

 

Il faut mettre RegexPatternHelper.prg dans le repertoire 'Prog' et l'ajouter a Set Proc

 

 

 

Voir

(1)    L’exemple

(2)    La docu dans RegexPatternHelper.prg en haut

 

Comment est-ce que ca marche ?

>> Regarder la definition dans le code.  Html ne fait pas un bon travail si je l'inclus ici 

 

(1)    On commence d’abord par mettre les lignes de la définition dans une collection.  La clef sera la partie gauche de la ligne (eg ddmmyyyy_slash ) et le contenu sera la partie droite (eg \b(\/\d{4})\b)

(2)    Puis on parcourt toutes les définitions pour en extraire les définitions dépendantes (eg ddmm_slash dépend de ddmm_29_slash, ddmm_30_slash et de ddmm_31_slash

(3)    Puis on fait un tri (topological sort) qui va retourner un ordre d’évaluation.  Eg, il faut évaluer ddmm_29_slash, ddmm_30_slash et ddmm_31_slash avant d’évaluer  ddmm_slash.

(4)    Ayant obtenu un ordre d’évaluation on va traiter la collection dans cet ordre.  Le traitement est simple, juste remplacer la définition.  L’astuce est de le faire dans le bon ordre.

 

 

Ps : il est possible de mettre les définitions courantes dans un champ memo d’une table incluse dans le projet

Code source :
*---------------------------------------------------------------------------
function do_it()

  local s

text to s noshow
global definitions
d29          (0[1-9]|1[0-9]|2[0-9])
d30          (0[1-9]|1[0-9]|2[0-9]|3[0])
d31          (0[1-9]|1[0-9]|2[0-9]|3[01])

months29      02
months30      (0[469])|(11)
months31      (0[13578])|(1[02])

# EUR
with /
ddmmyyyy_slash    \b(<ddmm_slash>\/\d{4})\b
ddmmyy_slash    \b(<ddmm_slash>\/\d{2})\b

ddmm_slash    <ddmm_29_slash>|<ddmm_30_slash>|<ddmm_31_slash>
ddmm_29_slash  <d29>\/<months29>
ddmm_30_slash  <d30>\/<months30>
ddmm_31_slash  <d31>\/<months31>

#with -
ddmmyyyy_hyphen  \b<ddmm_hyphen>-\d{4}\b
ddmmyy_hyphen  \b<ddmm_hyphen>-\d{2}\b

ddmm_hyphen    <ddmm_29_hyphen>|<ddmm_30_hyphen>|<ddmm_31_hyphen>
ddmm_29_hyphen  <d29>-<months29>
ddmm_30_hyphen  <d30>-<months30>
ddmm_31_hyphen  <d31>-<months31>

# US
with /
mmddyyyy_slash  \b<mmdd_slash>\/\d{4}\b
mmddyy_slash  \b<mmdd_slash>\/\d{2}\b

mmdd_slash    <mmdd_29_slash>|<mmdd_30_slash>|<mmdd_31_slash>
mmdd_29_slash  <months29>\/<d29>
mmdd_30_slash  <months30>\/<d30>
mmdd_31_slash  <months31>\/<d31>

with -
mmddyyyy_hyphen  \b<mmdd_hyphen>\/\d{4}\b
mmddyy_hyphen  \b<mmdd_hyphen>\/\d{2}\b

mmdd_hyphen    <mmdd_29_hyphen>|<mmdd_30_hyphen>|<mmdd_31_hyphen>
mmdd_29_hyphen  <months29>-<d29>
mmdd_30_hyphen  <months30>-<d30>
mmdd_31_hyphen  <months31>-<d31>

# yymmdd or yyyymmdd
with /
yyyymmdd_slash  \b\d{4}\/<mmdd_slash>\b
yymmdd_slash  \b\d{2}\/<mmdd_slash>\b

with -
yyyymmdd_hyphen  \b\d{4}-<mmdd_hyphen>\b
yymmdd_hyphen  \b\d{2}-<mmdd_hyphen>\b

endtext

  local Success
  Success = TRUE

  local obj

  local p1, p2

  && we accept dates like dd/mm/yy or dd/mm/yyyy

  do case
  case !m.Success

  case !RegexPatternHelper_Object(@m.obj)
    assert FALSE
    Success = FALSE

  && get first pattern
  case !m.obj.Construct(@m.p1, m.s, 'ddmmyy_slash')
    assert FALSE
    Success = FALSE

  && get second pattern
  case !m.obj.Construct(@m.p2, m.s, 'ddmmyyyy_slash')
    assert FALSE
    Success = FALSE

  && Or patterns
  case !m.obj.Or(@m.p1, m.p1, m.p2)
    assert FALSE
    Success = FALSE

  otherwise
    ?' pattern'
    ?m.p1
  endcase

text to s noshow
Messieurs,
le 01/03/9999999 , 189/12/2004, 22/04/2008(01/01/2009)
34/12/2008

le 01/03/9999999 , 189/12/04, 22/04/08(01/01/09)
34/12/28

le 01-03-9999999 , 189-12-04, 22-04-08(01-01-09)
34-12-28

le 01-03-9999999 , 189-12-2004, 22-04-2008(01-01-2009)
34-12-2008
endtext


  local RegExObj
  do case
  case !m.Success

  case !m.RegEx_Object(@m.RegExObj, TRUE, FALSE, m.p1)
    assert FALSE
    Success = FALSE

  otherwise
    MatchObj = m.RegExObj.Execute(m.s)

     with m.MatchObj

      for i = 0 to .Count - 1
       with .Item[m.i]
        ? .Value

       endwith
      endfor
     endwith
  endcase




endfunc
*---------------------------------------------------------------------------
Commentaires
le 23/05/2009, JpG a écrit :
Bien pensé, très bien réalisé. Chapeau.
On se sent tout petit...
Merci Grégory
JpG

le 24/05/2009, Gregory Adam a écrit :
Merci JpG

www.atoutfox.org - Site de la Communauté Francophone des Professionnels FoxPro - v3.4.0 - © 2004-2020.
Cette page est générée par un composant COM+ développé en Visual FoxPro 9.0-SP2-HF3