Page 1 sur 1

Ereg et Replace()

Publié : ven. 07/nov./2008 11:54
par lionel_om
Bonjour, je voudrais savoir si les expressions regulieres ont bien les fonctions avancees de remplacement de chaine :

Normallement avec les eReg, on peut creer des groupes (catcher) a l'aide de parentheses. Et donc je voudrais faire un ReplaceRegularExpression() avec comme motif de remplacement, un bout de ce qui a ete capture.
En PHP on peut utiliser les symboles '\\x' ou x represente l'index du goupe a remplacer.

Voila mon code :

Code : Tout sélectionner

Procedure.s Ereg_Replace(Text$, Pattern$, Replace$ = "", Options.l = #PB_RegularExpression_DotAll |  #PB_RegularExpression_Extended |  #PB_RegularExpression_AnyNewLine)
  hRegex = CreateRegularExpression(#PB_Any, Pattern$, Options)
  If hRegex
    Text$ = ReplaceRegularExpression(hRegex, Text$, Replace$)
    FreeRegularExpression(hRegex)
  Else
    Debug "Can't create a Regex with this pattern : " + Pattern$
  EndIf
  ProcedureReturn Text$
EndProcedure

; Code HTML : enleve les preprietes des balises (id, class, name, onXXX, ...)
Text$ = Ereg_Replace(Text$, "<([a-zA-Z]+)\ *[^>]+>", "<\\1>")
Ca ne marche pas: Chaque balise ouvrante ayant des parametres est remplacee par "<\\1>".

Quelqu'un sait si c'est possible en PB et dans ce cas, quel est le symbol de catch ?

Merci d'avance
/Lio

Publié : ven. 07/nov./2008 12:05
par Backup
c'est du 4.30 ??

parceque chez moi ça plante sur la constante "#PB_RegularExpression_DotAll " pb connais pas !! :)

en fait j'ai pas compris , tu veux remplacer quoi par quoi concrètement !! :)

en PHP
Les fonctions ereg_replace() et eregi_replace()

La fonction ereg_replace() dont la signature est la suivante :
chaîne ereg_replace(chaîne modele,chaîne remplacement,chaîne texte)
Permet de retourner la chaîne texte passée en arguments avec les occurrences trouvees remplacées par la chaîne de remplacement.
Pour utiliser les occurrences correspondant au modele dans la chaîne de remplacement, il suffit d'utiliser des parenthèses dans la chaîne modele, puis de faire référence à ces éléments dans la chaîne de remplacement en utilisant deux signes antislash suivi d'un numéro identifiant l'élément entre 0 et 9 (les numéros sont donnés par ordre d'imbriquement, puis de gauche à droite, le zéro représente la chaîne entière).
Le code suivant remplace Toto par <b>Toti Toto</b>... inutile mais formateur.

$Texte = "Bienvenue a Toto dans le mondes des expressions régulières";

$Texte = ereg_replace("To(to)","<b>\\1ti \\0</b>",$Texte);


Le code suivant (utilisation avancée des expressions régulières) remplace un URL par un hypertexte HTML (il remplace toute suite de caractères de ponctuations et alphanumériques commençant par http://, ou ftp:// par le même texte (sans le http://) entre balises HTML hypertexte...) :

$Texte = "Bienvenue sur http://www.commentcamarche.net cher ami";

$Texte = ereg_replace("(http://)(([[:punct:]]|[[:alnum:]])*)",
"<a href=\"\\0\">\\2</a>",$Texte);

La fonction eregi_replace() dont la signature est la suivante :
chaîne eregi_replace(chaîne modele,chaîne remplacement,chaîne texte)
effectue le même travail que sa consoeur ereg_replace(), à la différence près qu'elle n'est pas sensible à la casse (pas de différenciation minuscules/majuscules).
chez moi ça : ça marche

Code : Tout sélectionner

Procedure.s Ereg_Replace(Text$, Pattern$, Replace$ = "")
      hRegex = CreateRegularExpression(#PB_Any, Pattern$, Options)
      If hRegex
            Text$ = ReplaceRegularExpression(hRegex, Text$, Replace$)
            FreeRegularExpression(hRegex)
      Else
            Debug "Can't create a Regex with this pattern : " + Pattern$
      EndIf
      ProcedureReturn Text$
EndProcedure

; Code HTML : enleve les proprietes des balises (id, class, name, onXXX, ...)
CallDebugger
Text$="<rien> est son nom "

Text$ = Ereg_Replace(Text$, "<([a-zA-Z]+)\ *[^>]+>", "toto")
Debug Text$
cela remplace tout ce qui se trouve entre "<>" par "Toto"

Publié : ven. 07/nov./2008 14:19
par lionel_om
Je suis bien en 4.30.

En fait j'essaye de matcher toutes les expression HTML du type:
<name param="value"> et de les remplacer par <name>.
DoBro a écrit :cela remplace tout ce qui se trouve entre "<>" par "Toto"
Ce n'est pas ce que je veux car il faut que le nom de la balise soit conserve. Donc je ne peut pas utiliser une constante pour le texte de substitution dans ReplaceRegularExpression(): .

Dans les Expressions Regulieres on peu creer des groupes qui sont memorises et peut etre utilises lors d'un remplacement par eRegs.
Pour ca en PHP en utilise "\\x" comme je l'ai dit precedemment.

Donc l'expression "<([a-zA-Z]+)\ *[^>]+>" va renvoyer deux groupes:
index 0 : l'expression entiere catchee
index 1 : l'expression entre parenthese : ici le nom de la balise HTML qui est ouverte.
C'est deux groupes sont normallement memorise pour chaque match dans le text sur lequel l'eReg est appliquee. Et dans la plus part des langages utilisant les eReg, il est possible que le texte de remplacement soit un pattern qui peut utiliser ces groupes.

Comme en PHP le '\' est utilise pour de-specialiser, j'ai aussi essayer avec juste "\1", mais ca ne marche pas ! Des fois aussi il faut forcer a montrer que c'est bien une eReg que l'on utilise en ajoutant des caracteres speciaux identiques en debut et fin de chaine comme '#'. Mais "#\1#" ne donne pas de meilleurs resultat ! :wink:

Je voudrais donc savoir si c'est une limitation de PB ou si on peut vraiment les utiliser.

Merci de votre aide.
/Lio

Publié : ven. 07/nov./2008 16:04
par lionel_om
Etant presque sur que ce que je cherche n'a pas ete implemente sous PB, j'ai fait une fonction pour supprimer toutes les proprietes des tags et enlever les commentaires.

Le code est ci-dessous, mais si qq1 trouve comment vraiment resoudre ce 'bug' ou non implementation, merci bien de poster.

Voila le code:

Code : Tout sélectionner

Enumeration 0
  #STATE_OUT_OF_TAG
  #STATE_INSIDE_TAG
  #STATE_READING_TAG_NAME
  #STATE_READING_TAG_ARGS
  #STATE_IN_SQUOTE_TEXT
  #STATE_IN_DQUOTE_TEXT
  #STATE_COMMENT
EndEnumeration


Procedure.s RemoveTagProperties(Text$)
  *char.Byte = @Text$
  *save.Byte = #Null
  Length.l = Len(Text$) + 1
  State = #STATE_OUT_OF_TAG
  While *char\b <> 0 And Length > 0
    s$ = Chr(*char\b & $FF)
    If *char\b <> '\'
      Select *char\b & $FF
        
        Case '<'
          If State = #STATE_OUT_OF_TAG
            State = #STATE_INSIDE_TAG
          EndIf
          
        Case '>'
          Select State
            Case #STATE_INSIDE_TAG, #STATE_READING_TAG_NAME
              State = #STATE_OUT_OF_TAG
            Case #STATE_READING_TAG_ARGS
              If *Save <> #Null
                CopyMemory(*char, *Save, Length)
                *char = *Save
                *Save = #Null
                State = #STATE_OUT_OF_TAG
              Else
                Debug "Error !!!!"
              EndIf
          EndSelect
        
        Case ' ', 10, 13, 9
          If State = #STATE_READING_TAG_NAME
            State = #STATE_READING_TAG_ARGS
            *Save = *char
          EndIf

        Case 'a' To 'z', 'A' To 'Z'
          If State = #STATE_INSIDE_TAG
            State = #STATE_READING_TAG_NAME
          EndIf
        
        Case '!'
          If State = #STATE_INSIDE_TAG
            car.c = PeekC(*char+1)
            If car = '-' And PeekC(*char+2) = '-'
              *Save = *char-1
              *char  + 3
              Length - 3
              State = #STATE_COMMENT
            EndIf
          EndIf
        
        Case '-'
          If State = #STATE_COMMENT
            If PeekC(*char+1) = '-' And PeekC(*char+2) = '>'
              *char  + 3
              Length - 3
              If *Save <> #Null
                CopyMemory(*char, *Save, Length)
                *char = *Save - 1
                Length + 1
                *Save = #Null
              Else
                Debug "Error !!!!"
              EndIf
              State = #STATE_OUT_OF_TAG
            EndIf
          EndIf
      
        Case '"'
          If State = #STATE_READING_TAG_ARGS
            State = #STATE_IN_DQUOTE_TEXT
          ElseIf State = #STATE_IN_DQUOTE_TEXT
            State = #STATE_READING_TAG_ARGS
          EndIf
        
        Case Asc("'") ; 39
          If State = #STATE_READING_TAG_ARGS
            State = #STATE_IN_SQUOTE_TEXT
          ElseIf State = #STATE_IN_SQUOTE_TEXT
            State = #STATE_READING_TAG_ARGS
          EndIf
      
      EndSelect
    EndIf
    
    *char  + 1
    Length - 1
  Wend
  *char\b = 0
  ProcedureReturn Text$
EndProcedure


Procedure.s GetFileContent(FileName$, EndLineChars$ = #CRLF$, FileNotFound$ = "", KeepEmptyLines.b = #True)
  Protected Retour$ = "", hFile.l, Line$
  hFile = ReadFile(#PB_Any, FileName$)
  If hFile
    While Eof(hFile) = #Null
      Line$ = ReadString(hFile)
      If Len(Line$) Or KeepEmptyLines
        Retour$ + Line$ + EndLineChars$
      EndIf
    Wend
    CloseFile(hFile)
  Else
    ProcedureReturn FileNotFound$
  EndIf
  ProcedureReturn Retour$
EndProcedure


File$ = OpenFileRequester("Select a file", "", "HTML Files|*.html;*.htm|All files|*.*", 0)
If File$
  Content$ = GetFileContent(File$)
  SafeContent$ = RemoveTagProperties(Content$)
  Debug SafeContent$
EndIf
/Lio

Publié : ven. 07/nov./2008 16:59
par lionel_om
J'ai ete mauvaise langue :
Voila ce qui ne marchait pas :

Code : Tout sélectionner

Text$ = Ereg_Replace(Text$, "<([a-zA-Z]+)\ *[^>]+>", "</\1>")
Le code total est donc :

Code : Tout sélectionner

Procedure.s Ereg_Replace(Text$, Pattern$, Replace$ = "", Options.l = #PB_RegularExpression_DotAll |  #PB_RegularExpression_Extended |  #PB_RegularExpression_AnyNewLine)
  hRegex = CreateRegularExpression(#PB_Any, Pattern$, Options)
  If hRegex
    Text$ = ReplaceRegularExpression(hRegex, Text$, Replace$)
    FreeRegularExpression(hRegex)
  Else
    Debug "Can't create a Regex with this pattern : " + Pattern$
  EndIf
  ProcedureReturn Text$
EndProcedure

; Code HTML : enleve les preprietes des balises (id, class, name, onXXX, ...) 
Text$ = Ereg_Replace(Text$, "<([a-zA-Z]+)\ *[^>]+>", "</\1>")
Debug Text$ 
/Lio

Publié : jeu. 18/déc./2008 15:54
par lionel_om
Bonjour tout le monde,

Le probleme est revenu et le pattern que j'utilise ne marche plus apparement... comme ca du jour au lendemain... sans rien change (mm sans recompiler il me semble).

Voici un test:

Code : Tout sélectionner

Options.l = #PB_RegularExpression_DotAll |  #PB_RegularExpression_Extended |  #PB_RegularExpression_AnyNewLine
Pattern$ = "<(?<1>[a-zA-Z]+)\ *[^>]+>"
Text$ = " <p class=hello> mid <a href=test><script> text inside </script></a> after"
Replace$ = "</\1>"

hRegex = CreateRegularExpression(#PB_Any, Pattern$, Options)
If hRegex
  Debug ReplaceRegularExpression(hRegex, Text$, Replace$)
  FreeRegularExpression(hRegex)
Else
  Debug "Can't create a Regex with this pattern : " + Pattern$
EndIf
Ca devrait renvoyer :
<p> mid <a><script> text inside </script></a> after
Si qq1 sait comment fixer ce probleme, I need help !
Merci d'avance de votre aide !

/Lio