Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Pour migrer des fonctions regex en fonctions pcre automatiquement.

23 réponses
Avatar
Jean-Francois Ortolo
Bonjour

J'ai l'honneur ( excusez du peu ;) ) de présenter une solution de
migration semi automatique, des fonctions de type regex: split(),
ereg(), eregi(), ereg_replace(), et eregi_replace(), vers leurs
équivalents de type pcre : preg_split(), preg_match(), et preg_replace().

En effet, ces fonctiosn regex, disparaîtront à la version PHP 6, et
il est donc souhaitable de pouvoir migrer ses sites vers les nouvelles
fonctions.

Compte tenu du fait que celà intéresse avant tout les programmeurs
php, j'espère que le modérateur va laisser passer ce message, bien que
ses outils relèvent plutôt de la programmation Shell et Awk. ;(


Cette solution se compose d'un script en Bourne Shell migration.sh, à
placer dans la racine du site web à migrer, et d'un script awk
filtre.awk à placer aussi dans la racine du site à migrer.

Voici le code des ces deux scripts :

D'abord, migration.sh

La variable dir_init doit être alimentée avec le répertoire dans
lequel est installé ce script ( répertoire racine du site web ).

Ce script est censé être lancé à partir du compte root.

La variable perm doit être alimentée avec le propriétaire et groupe
des scripts php à migrer.

Excusez-moi du fait que ces instructions sont sous forme de
citations, j'ai la flemme d'enlever manuellement les débuts de lignes.


> #!/bin/sh
>
> # Propriétaire et groupe
> # des scripts *.php
> perm="root:root"
>
> # Variables de configuration, c'est le répertoire de départ.
> dir_init="/var/www/html/php"
>
> # Et le script awk de filtre.
> filtre_awk=${dir_init}"/filtre.awk"
>
> # On calcule le répertoire absolu courant.
> # Quand le paramètre n'est pas présent,
> # c'est le répertoire de départ, sinon
> # c'est le paramètre du script.
> if [ $# -eq 0 ]; then
> dir=${dir_init}
> else
> dir=$1
> fi
>
> # Positionnement dans le répertoire courant.
> cd ${dir}
>
> # On parcourt le répertoire courant en sélectionnant
> # tous les scripts php.
> for i in `ls *.php 2>/dev/null`; do
> if [ -f $i ]; then
> file=${dir}"/"${i}
> file2=${dir}"/super_new_"${i}".txt"
>
> # Traitement du script *.php,
> # là on se contente d'afficher son nom
> # avec son chemin absolu.
> #
> echo ${file} > /root/tmp2.txt
> echo ${file2} >> /root/tmp2.txt
> echo "" >> /root/tmp2.txt
>
> awk -f ${filtre_awk} -- ${file} 1>${file2} 2>>/root/tmp2.txt
>
> chown $perm ${file2}
> chmod 777 ${file2}
>
> t1=`ls -l ${file} | awk '{ print $5; }'`
> t2=`ls -l ${file2} | awk '{ print $5; }'`
>
> if [ ${t1} -ne ${t2} ]; then
> cat /root/tmp2.txt >> /root/tmp.txt
> fi
> fi
> done
>
> # On lit tous les sous-répertoires du répertoire courant,
> # et on relance le même script, avec ces sous-répertoires
> # comme paramètre, pour que ces processus fils
> # se positionnent sur ces sous-répertoires.
> #
> for j in `ls -d * 2>/dev/null`; do
> if [ -d $j ]; then
>
> # Calcul du sous-répertoire absolu.
> direct=${dir}"/"${j}
>
> ${dir_init}/migration.sh ${direct}
> fi
> done
>
> # A la fin du script, on remonte vers le répertoire
> # père.
> cd ..
>
> exit 0


Ensuite, voici le code du script filtre.awk :


> function change(param)
> {
> p=split(param, tableau, "");
>
> drapeau=0;
> n=0;
>
> for(i=1; i<=p; i++)
> {
> t=tableau[i];
>
> if(drapeau!=0)
> {
> if(n==0)
> {
> if(t=="\\")
> {
> n++;
> }
> else
> {
> if(t==s)
> {
> chaine=chaine "/" s;
> break;
> }
> else
> chaine=chaine t;
> }
> }
> else
> {
> if(t=="\\")
> n++;
> else
> {
> d="";
> for(k=1; k<=n; k++)
> d=d "\\";
>
> chaine=chaine d;
>
> q=n;
> if(((2*int(q/2.0))==n)&&(t==s))
> {
> chaine=chaine "/" s;
> break;
> }
> else
> chaine=chaine t;
>
> n=0;
> }
> }
>
> }
> else
> {
> if((t=="'")||(t=="\""))
> {
> drapeau=1;
> s=t;
> chaine=t "/";
> }
> # Début de chr(nombre)
> # ou de variable masque.
> else if((t=="c")||(t=="$"))
> {
> chaine=t;
> break;
> }
> }
> }
>
> i++;
>
> for(; i<=p; i++)
> {
> t=tableau[i];
> chaine=chaine t;
> }
>
> return(chaine);
> }
> function change_i(param)
> {
> p=split(param, tableau, "");
>
> drapeau=0;
> n=0;
>
> for(i=1; i<=p; i++)
> {
> t=tableau[i];
>
> if(drapeau!=0)
> {
> if(n==0)
> {
> if(t=="\\")
> {
> n++;
> }
> else
> {
> if(t==s)
> {
> chaine=chaine "/i" s;
> break;
> }
> else
> chaine=chaine t;
> }
> }
> else
> {
> if(t=="\\")
> n++;
> else
> {
> d="";
> for(k=1; k<=n; k++)
> d=d "\\";
>
> chaine=chaine d;
>
> q=n;
> if(((2*int(q/2.0))==n)&&(t==s))
> {
> chaine=chaine "/i" s;
> break;
> }
> else
> chaine=chaine t;
>
> n=0;
> }
> }
>
> }
> else
> {
> if((t=="'")||(t=="\""))
> {
> drapeau=1;
> s=t;
> chaine=t "/";
> }
> # Début de chr(nombre)
> # ou de variable masque.
> else if((t=="c")||(t=="$"))
> {
> chaine=t;
> break;
> }
> }
> }
>
> i++;
>
> for(; i<=p; i++)
> {
> t=tableau[i];
> chaine=chaine t;
> }
>
> return(chaine);
> }
> {
> line=$0;
> line2=$0;
>
> if(line ~ /=[ \t]*split[ ]*\(/)
> {
> r=split(line, tableau, /=[ \t]*split[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "= preg_split(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /eregi[ ]*\(/)
> {
> split(line, tableau, /eregi[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_match(";
> v=change_i(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /ereg[ ]*\(/)
> {
> split(line, tableau, /ereg[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_match(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /eregi_replace[ ]*\(/)
> {
> split(line, tableau, /eregi_replace[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_replace(";
> v=change_i(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /ereg_replace[ ]*\(/)
> {
> split(line, tableau, /ereg_replace[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_replace(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> printf ("%s\n", line);
>
> if(line!=line2)
> {
> print "D'abord:" line2 " Ensuite:" line > "/dev/stderr"
> }
> }


A la fin de la migration, vous avez le fichier de logs /root/tmp.txt
qui contient les chemins absolus des scripts php avant et après
migration, ainsi que les lignes des fonctions migrées.

Ce fichier ne contient que les scripts modifiés, pas les scripts
inchangés.

Pour arranger le formattage, je suggère de séparer ce fichier de
logs, en deux fichiers indexé de 1 à n, n étant le nombre de fichiers
modifiés.

Pour celà :

cat tmp.txt | awk 'BEGIN{ i=0; j=0; }{ if(length($0)<5) { i++; j++;
if(j==1) print i; } else if ($0 !~ /Ensuite/) { j=0; print $0; } }' >
fichiers.txt


cat tmp.txt | awk 'BEGIN{ i=0; j=0; }{ if(length($0)<5) { i++; j++;
if(j==1) print i; } else if ($0 ~ /Ensuite/) { j=0; print $0; } }' | awk
'{ for(i=2; i<=NF; i++) if($i != "Ensuite:") printf("%s ", $i); else
printf(" "); printf("\n"); }' > fonctions.txt


Ensuite, vous aurez dans fichiers.txt la liste indexés de 1 à n des
chemins absolus des fichiers sources et cibles par paires, et dans
fonctions.txt la liste indexée des fonctions avant et après migration,
par groupes de fonctions pour chaque fichiers modifiés.

Dans les deux cas, l'index va de 1 à n, et n a la même valeur dans
les deux cas.

Il faut obligatoirement vérifier dans le fichier fonctions.txt qu'il
n'y a pas d'erreur lors de la migration des fonctions.

Théoriquement la seule erreur peut résulter du fait que l'expression
rationnelle est contenue dans une variable php ( commençant par $ le
caractère dollar ). Dans ce cas évidemment, il n'y a pas d'autre
solution que d'éditer manuellement le fichier cible correspondant ( de
même index dans le fichiers fichiers.txt ), pour modifier cette variable
php qui sert d'expression rationnelle.


Comme conclusion, je serais intéressé à ce que vous m'indiquiez les
erreurs de programmation éventuelles que vous voyez, car je suis en
train de faire cette migration sur mon ordinateur, pour mon site
www.pronostics-courses.fr versions locale et remote, ainsi que pour le
site www.lescourses.com, mon site partenaire, que j'ai copié sur mon
ordinateur. ;) Celà me permettrait de diminuer le risque d'erreurs.

Je suis aussi intéressé par vos remarques et suggestions, compte tenu
du fait que cette topique de migration automatisée de fonctions regex
vers des fonctions pcre, avait été abordée il y de celà quelques
semaines ou mois.

Bien à vous.

Amicalement.

Jean-François Ortolo

--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.

Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.

10 réponses

1 2 3
Avatar
Jean-Francois Ortolo
Bonsoir

Voici la toute dernière version, permettant de prendre en compte
correctement le cas où la fonction trim() ( aussi bien que chr() )
figure dans l'expression rationnelle regex de départ à migrer vers une
expression rationnelle pcre.

Donc au final, les deux seules fonctions admises dans ces expressions
rationnelles, sont chr() et trim(). S'il s'avérait qu'il puisse y avoir
d'autres fonctions de traitement de chaînes de caractères éventuellement
rencontrées dans la réalité, merci de me le dire, cependant, il
suffirait dans ce cas d'une modification mineure, pour élargir le "else"
indiquant la présence du pattern trim, à d'autres patterns de noms de
fonctions, le traitement quant à lui restant identique.

Merci beaucoup de vos suggestions à ce sujet.

Le code de migration.sh est le même que précédemment, donc je ne
donne que le code de filtre.awk sous sa forme définitive :

--------------------------------------------------------------

function change(param)
{
# Fin d'expression rationnelle
# trouvée.
fin_trouve=0;

# Quote simple ou double
# de fin d'expression
# rationnelle partielle
# ou globale.
quote_trouve=0;

p=split(param, tableau, "");

# n = nombre de caractères backslashes
# ( ) rencontrés.
n=0;

# Initialisation
# du premier paramètre
# de la fonction pcre.
chaine=""/".";

for(i=1; i<=p; i++)
{
t=tableau[i];

if(t=="$")
{
quote_trouve=0;

# On suppose que les variables
# sont toujours accolées
# aux autres expressions,
# par un point, et que
# leurs noms ne contiennent pas
# de point.
while((i<=p)&&(t!=".")&&(t!=","))
{
# Pas d'espace
# dans un nom de variable.
if((t!=" ")&&(t!="t"))
chaine=chaine t;

i++;
t=tableau[i];
}

if(i>p)
{
# Fin de tableau[i]
# rencontré, sans
# atteindre la fin
# de l'expression rationnelle,
# donc erreur.
print "Erreur: expression rationnelle sur plusieurs lignes: " param
" " chaine > "/dev/stderr";

# On sort de la boucle.
break;
}
else if(t==".")
{
# L'expression rationnelle
# continue avec une autre
# expression accolée.
chaine=chaine t;
}
else
{
# Fin de l'expression rationnelle
# rencontrée.
fin_trouve=1;

# t n'a pas été affecté,
# elle le sera en sortie de boucle.
#
#
# On sort de la boucle.
break;
}
}
else if((t=="t")||(t=="c"))
{
if(t=="t")
{
# début de trim(
pattern="trim";
}
else
{
# Début de chr(
pattern="chr";
}

w=split(pattern, tab, "");

for(x=1; ((i<=p)&&(x<=w)); x++)
{
if(t==tab[x])
{
chaine=chaine tab[x];

i++;
t=tableau[i];
}
else
{
# Erreur, token non prévu.
break;
}
}

if(x<=w)
{
# Le token n'est pas
# conforme.
print "Erreur: token non prévu: " param " " chaine > "/dev/stderr";

#" On sort de la boucle.
break;
}
else
{
# Recherche de la parenthèse
# ouvrante,
# puis suite du traitement.
while((i<=p)&&(t!="("))
{
i++;
t=tableau[i];
}

chaine=chaine "(";

i++;
t=tableau[i];

if(pattern=="chr")
{
# Dans ce cas, on cherche
# la parenthèse fermante,
# suivie le cas échéant
# d'un point ( . )
# ou la virgule de fin
# d'expression rationnelle.
while((i<=p)&&(t!=")"))
{
chaine=chaine t;

i++;
t=tableau[i];
}

chaine=chaine ")";

# On cherche un point
# Ou la virgule de fin.
i++;
t=tableau[i];
while((i<=p)&&(t!=".")&&(t!=","))
{
# On prend le point,
# mais pas la virgule.
if(t!=",")
chaine=chaine t;
i++;
t=tableau[i];
}

# La fin de l'expression rationnelle
# a été trouvée, on sort.
if(t==",")
{
fin_trouve=1;

break;
}
else
# C'est le point.
chaine=chaine t;
}
else
{
# Cas de la fonction trim().
z=1;

# On recherche la première parenthèse
# fermante, matchant
# la parenthèse ouvrante
# déjà rencontrée.

while((i<=p)&&(z>0))
{
if(t=="")
{
n++;
}
else
{
for(x=1; x<=n; x++)
chaine=chaine "";

q=n;

chaine=chaine t;

if((q==0)||((2*int(q/2.0))==n))
{
if(t==")")
{
z--;

if(z==0)
{
# Parenthèse fermante matchant
# trouvée, on sort de la boucle.
break;
}
}
else if(t=="(")
{
z++;

}


}

n=0;
}

i++;
t=tableau[i];
}

n=0;

if(i>p)
{
# Le token n'est pas
# conforme.
print "Erreur: token non prévu: " param " " chaine >
"/dev/stderr";

# On sort de la boucle.
break;
}
else
{
# On cherche un point
# Ou la virgule de fin.
i++;
t=tableau[i];
while((i<=p)&&(t!=".")&&(t!=","))
{
# On prend le point,
# mais pas la virgule.
if(t!=",")
chaine=chaine t;
i++;
t=tableau[i];
}

# La fin de l'expression rationnelle
# a été trouvée, on sort.
if(t==",")
{
fin_trouve=1;

break;
}
else
# C'est le point.
chaine=chaine t;
}
}
}
}
else if((t==""")||(t=="'"))
{
chaine=chaine t;

# Mémorisation du type de quote
# ( double ou simple )
# encadrant l'expression
# rationnelle.
s=t;

i++;
t=tableau[i];
while((i<=p)&&(quote_trouve==0))
{
if(t=="")
{
n++;
}
else
{
for(x=1; x<=n; x++)
chaine=chaine "";

q=n;

indic=0;
# Echappement
# au cas où.
if((n>0)&&((2*int(q/2.0))==n)&&((t=="&")||(t=="+")||(t==s)))
{
indic=1;

# On n'échappe pas
# le signe +
# s'il est précédé
# de ]
# ( expression rationnelle ).
if(t=="+")
{
if(tableau[i-1]!="]")
chaine=chaine "";
else
indic=0;
}
else if(t=="&")
chaine=chaine "";
else if(t==s)
chaine=chaine "";
}

chaine=chaine t;

n=0;

# quote sans échappement :
# La fin de l'expression
# rationnelle en cours
# a été trouvée.
if((indic==0)&&(t==s))
quote_trouve=1;
}

i++;
t=tableau[i];
}

# On a trouvé la quote terminale
# de l'expression rationnelle en cours,
# donc on cherche le point,
# ou la virgule qui marque la fin
# de l'expression rationnelle globale.

while((i<=p)&&(t!=".")&&(t!=","))
{
# On prend le point,
# mais pas la virgule.
if(t!=",")
chaine=chaine t;
i++;
t=tableau[i];
}

# La fin de l'expression rationnelle
# a été trouvée, on sort.
if(t==",")
{
fin_trouve=1;

break;
}
else
# C'est le point.
chaine=chaine t;
}
}

if(fin_trouve==1)
{
# tableau[i]==","

# On complète la chaîne,
# de manière à l'adapter
# à la norme pcre.
chaine=chaine "."/",";

# Et puis, on complète
# le reste de la fonction.
i++;

while(i<=p)
{
t=tableau[i];

chaine=chaine t;

i++;
}
}

return(chaine);
}
function change_i(param)
{
# Fin d'expression rationnelle
# trouvée.
fin_trouve=0;

# Quote simple ou double
# de fin d'expression
# rationnelle partielle
# ou globale.
quote_trouve=0;

p=split(param, tableau, "");

# n = nombre de caractères backslashes
# ( ) rencontrés.
n=0;

# Initialisation
# du premier paramètre
# de la fonction pcre.
chaine=""/".";

for(i=1; i<=p; i++)
{
t=tableau[i];

if(t=="$")
{
quote_trouve=0;

# On suppose que les variables
# sont toujours accolées
# aux autres expressions,
# par un point, et que
# leurs noms ne contiennent pas
# de point.
while((i<=p)&&(t!=".")&&(t!=","))
{
# Pas d'espace
# dans un nom de variable.
if((t!=" ")&&(t!="t"))
chaine=chaine t;

i++;
t=tableau[i];
}

if(i>p)
{
# Fin de tableau[i]
# rencontré, sans
# atteindre la fin
# de l'expression rationnelle,
# donc erreur.
print "Erreur: expression rationnelle sur plusieurs lignes: " param
" " chaine > "/dev/stderr";

# On sort de la boucle.
break;
}
else if(t==".")
{
# L'expression rationnelle
# continue avec une autre
# expression accolée.
chaine=chaine t;
}
else
{
# Fin de l'expression rationnelle
# rencontrée.
fin_trouve=1;

# t n'a pas été affecté,
# elle le sera en sortie de boucle.
#
#
# On sort de la boucle.
break;
}
}
else if((t=="t")||(t=="c"))
{
if(t=="t")
{
# début de trim(
pattern="trim";
}
else
{
# Début de chr(
pattern="chr";
}

w=split(pattern, tab, "");

for(x=1; ((i<=p)&&(x<=w)); x++)
{
if(t==tab[x])
{
chaine=chaine tab[x];

i++;
t=tableau[i];
}
else
{
# Erreur, token non prévu.
break;
}
}

if(x<=w)
{
# Le token n'est pas
# conforme.
print "Erreur: token non prévu: " param " " chaine > "/dev/stderr";

#" On sort de la boucle.
break;
}
else
{
# Recherche de la parenthèse
# ouvrante,
# puis suite du traitement.
while((i<=p)&&(t!="("))
{
i++;
t=tableau[i];
}

chaine=chaine "(";

i++;
t=tableau[i];

if(pattern=="chr")
{
# Dans ce cas, on cherche
# la parenthèse fermante,
# suivie le cas échéant
# d'un point ( . )
# ou la virgule de fin
# d'expression rationnelle.
while((i<=p)&&(t!=")"))
{
chaine=chaine t;

i++;
t=tableau[i];
}

chaine=chaine ")";

# On cherche un point
# Ou la virgule de fin.
i++;

# L'un ou l'autre
# a été trouvé, donc
# on actualise chaine.
t=tableau[i];
while((i<=p)&&(t!=".")&&(t!=","))
{
# On prend le point,
# mais pas la virgule.
if(t!=",")
chaine=chaine t;
i++;
t=tableau[i];
}

# La fin de l'expression rationnelle
# a été trouvée, on sort.
if(t==",")
{
fin_trouve=1;

break;
}
else
# C'est le point.
chaine=chaine t;
}
else
{
# Cas de la fonction trim().
z=1;

# On recherche la première parenthèse
# fermante, matchant
# la parenthèse ouvrante
# déjà rencontrée.

while((i<=p)&&(z>0))
{
if(t=="")
{
n++;
}
else
{
for(x=1; x<=n; x++)
chaine=chaine "";

q=n;

chaine=chaine t;

if((q==0)||((2*int(q/2.0))==n))
{
if(t==")")
{
z--;

if(z==0)
{
# Parenthèse fermante matchant
# trouvée, on sort de la boucle.
break;
}
}
else if(t=="(")
{
z++;

}


}

n=0;
}
i++;
t=tableau[i];
}

n=0;

if(i>p)
{
# Le token n'est pas
# conforme.
print "Erreur: token non prévu: " param " " chaine >
"/dev/stderr";

# On sort de la boucle.
break;
}
else
{
# On cherche un point
# Ou la virgule de fin.
i++;
t=tableau[i];
while((i<=p)&&(t!=".")&&(t!=","))
{
# On prend le point,
# mais pas la virgule.
if(t!=",")
chaine=chaine t;
i++;
t=tableau[i];
}

# La fin de l'expression rationnelle
# a été trouvée, on sort.
if(t==",")
{
fin_trouve=1;

break;
}
else
# C'est le point.
chaine=chaine t;
}
}
}
}
else if((t==""")||(t=="'"))
{
chaine=chaine t;

# Mémorisation du type de quote
# ( double ou simple )
# encadrant l'expression
# rationnelle.
s=t;

i++;
t=tableau[i];
while((i<=p)&&(quote_trouve==0))
{
if(t=="")
{
n++;
}
else
{
for(x=1; x<=n; x++)
chaine=chaine "";

q=n;

indic=0;
# Echappement
# au cas où.
if((n>0)&&((2*int(q/2.0))==n)&&((t=="&")||(t=="+")||(t==s)))
{
indic=1;

# On n'échappe pas
# le signe +
# s'il est précédé
# de ]
# ( expression rationnelle ).
if(t=="+")
{
if(tableau[i-1]!="]")
chaine=chaine "";
else
indic=0;
}
else if(t=="&")
chaine=chaine "";
else if(t==s)
chaine=chaine "";
}

chaine=chaine t;

n=0;

# quote sans échappement :
# La fin de l'expression
# rationnelle en cours
# a été trouvée.
if((indic==0)&&(t==s))
quote_trouve=1;
}

i++;
t=tableau[i];
}

# On a trouvé la quote terminale
# de l'expression rationnelle en cours,
# donc on cherche le point,
# ou la virgule qui marque la fin
# de l'expression rationnelle globale.
while((i<=p)&&(t!=".")&&(t!=","))
{
# On prend le point,
# mais pas la virgule.
if(t!=",")
chaine=chaine t;
i++;
t=tableau[i];
}

# La fin de l'expression rationnelle
# a été trouvée, on sort.
if(t==",")
{
fin_trouve=1;

break;
}
else
# C'est le point.
chaine=chaine t;
}
}

if(fin_trouve==1)
{
# tableau[i]==","

# On complète la chaîne,
# de manière à l'adapter
# à la norme pcre.
chaine=chaine "."/i",";

# Et puis, on complète
# le reste de la fonction.
i++;

while(i<=p)
{
t=tableau[i];

chaine=chaine t;

i++;
}
}

return(chaine);
}
{
line=$0;
line2=$0;

if(line ~ /=[ t]*split[ ]*(/)
{
r=split(line, tableau2, /=[ t]*split[ ]*(/);

for(l=1; l<=r; l++)
{
u=tableau2[l];

if(l==1)
line=u;
else
{
line=line "= preg_split(";
v=change(u);
line=line v;
}
}
}

if(line ~ /eregi[ ]*(/)
{
r=split(line, tableau2, /eregi[ ]*(/);

for(l=1; l<=r; l++)
{
u=tableau2[l];

if(l==1)
line=u;
else
{
line=line "preg_match(";
v=change_i(u);
line=line v;
}
}
}

if(line ~ /ereg[ ]*(/)
{
r=split(line, tableau2, /ereg[ ]*(/);

for(l=1; l<=r; l++)
{
u=tableau2[l];

if(l==1)
line=u;
else
{
line=line "preg_match(";
v=change(u);
line=line v;
}
}
}

if(line ~ /eregi_replace[ ]*(/)
{
r=split(line, tableau2, /eregi_replace[ ]*(/);

for(l=1; l<=r; l++)
{
u=tableau2[l];

if(l==1)
line=u;
else
{
line=line "preg_replace(";
v=change_i(u);
line=line v;
}
}
}

if(line ~ /ereg_replace[ ]*(/)
{
r=split(line, tableau2, /ereg_replace[ ]*(/);

for(l=1; l<=r; l++)
{
u=tableau2[l];

if(l==1)
line=u;
else
{
line=line "preg_replace(";
v=change(u);
line=line v;
}
}
}

printf ("%sn", line);
}

-----------------------------------------------------------------

Ouf, ouf...

Là encore, je vous prie de bien vouloir m'excuser de la longueur du
code, qui pourrait d'ailleur être raccourci en ne mettant qu'une seule
fonction change() avec un deuxième paramètre indiquant s'il faut ou non
ajouter i après le slash ( / ) terminant l'expression rationnelle migrée.

Sous cette forme, et compte tenu des limitations indiquées en haut du
message, qui peuvent être surmontées de la manière indiquée, je pense
que l'on peut considérer que c'est la version définitive, bêta.

Ces deux scripts filtre.awk et migration.sh , peuvent ainsi servir
pour très rapidement migrer ces fonctions regex obsolètes sous php 6,
vers les fonctions pcre, de façon à permettre à vos sites, de supporter
un hébergement php 6.

Il va de soi, que pour qu'un site soit compatible php 6, il y a aussi
d'autres conditions, mais je me contente d'apporter ma pierre à l'édifice...

Merci beaucoup de vos réponses, critiques et suggestions.

Bien à vous.

Amicalement.

Jean-François Ortolo

--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.

Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Avatar
Olivier Miakinen
Bonjour Jean-François,

Je n'ai pas trouvé le temps de tout lire, mais il faut que je publie mes
quelques remarques dès maintenant sinon je ne le ferai jamais.

Le 10/01/2010 18:10, Jean-Francois Ortolo a écrit :

J'avais des difficultés ptratique avec la version précédente, qui
n'était pas strictement automatique, car elle nécessitait des
vérifications manuelles.

Il semble que j'ai réussi à mettre au point une version entièrement
automatique, qui donne des messages d'erreurs quand il y a des erreurs,
dans le fihcier /root/tmp.txt Quand ce fichier ne contient que les
fichiers migrés, ( pas de token Erreur ) il n'y a pas d'erreur durant la
migration.

Voici le code :

D'abord, le filtre filtre.awk



Je n'ai lu que ça, et même que la fonction change() de ce script. Je
n'en ai eu le courage que parce que tu as abondamment commenté ce code,
ce dont je te remercie.

-----------------------------------------------------------

function change(param)
{
# Fin d'expression rationnelle
# trouvée.
fin_trouve=0;

# Quote simple ou double
# de fin d'expression
# rationnelle partielle
# ou globale.
quote_trouve=0;

p=split(param, tableau, "");



Attention, ceci n'est pas portable : c'est un gnuisme (code spécifique
gnu). Sur les versions de awk différentes de gawk, rien ne dit comment
on doit traiter le cas où le 3e paramètre de split() est une chaîne
vide.

# n = nombre de caractères backslashes
# ( ) rencontrés.
n=0;

# Initialisation
# du premier paramètre
# de la fonction pcre.
chaine=""/".";



Il m'a fallu quelques secondes pour comprendre cette ligne.
Personnellement j'aurais écrit :
chaine = '"/" . ';

Au fait, il y a ici une supposition implicite, à savoir que la regexp
posix ne contient jamais aucun caractère « / », aussi bien écrit de
façon littérale que caché dans une variable.

for(i=1; i<=p; i++)
{
t=tableau[i];

if(t=="$")
{
quote_trouve=0;

# On suppose que les variables
# sont toujours accolées
# aux autres expressions,
# par un point, et que
# leurs noms ne contiennent pas
# de point.



Ceci est une autre supposition qui correspond certainement à ton propre
code, mais pas forcément aux code des autres (il suffit de voir comme tu
n'as mis aucune espace dans la ligne qui suit alors que moi j'en aurais
mis exactement onze !)

while((i<=p)&&(t!=".")&&(t!=","))
{
# Pas d'espace
# dans un nom de variable.
if((t!=" ")&&(t!="t"))
chaine=chaine t;



... et si jamais le code d'origine avait le mauvais goût de contenir des
espaces après un nom de variable, elles seront impitoyablement virées
par la transformation ! ;-)


i++;
t=tableau[i];
}

if(i>p)
{
# Fin de tableau[i]
# rencontré, sans
# atteindre la fin
# de l'expression rationnelle,
# donc erreur.
print "Erreur: expression rationnelle sur plusieurs lignes: " param
" " chaine > "/dev/stderr";



Sauf erreur, « > &2 » me semble plus portable que « > /dev/stderr ».
Mais je peux me tromper.

[...]
else if((t=="t")||(t=="c"))
{
if(t=="t")
{
# début de trim(
pattern="trim";
}
else
{
# Début de chr(
pattern="chr";
}



Ok, ceci est un code très spécifique à tes propres habitudes, mais vu
que c'est bien documenté il doit être facile de rajouter d'autres
fonctions selon les besoins de chacun.


w=split(pattern, tab, "");



Même gnuisme que signalé plus haut.


[...]
else if((t==""")||(t=="'"))
{
chaine=chaine t;

# Mémorisation du type de quote
# ( double ou simple )
# encadrant l'expression
# rationnelle.
s=t;

i++;
t=tableau[i];
while((i<=p)&&(quote_trouve==0))
{
if(t=="")
{
n++;
}



J'avoue que je n'ai pas compris le traitement des « » :
- pourquoi tu comptes le nombre de tous les successifs au lieu de les
recopier dans 'chaine' dès que tu en as deux d'affilée ;
- comment tu gères les $, " et '.

else
{
for(x=1; x<=n; x++)
chaine=chaine "";

q=n;

indic=0;
# Echappement
# au cas où.
if((n>0)&&((2*int(q/2.0))==n)&&((t=="&")||(t=="+")||(t==s)))



Est-ce que le test ((2*int(q/2.0))==n) ne pourrait pas être remplacé
tout simplement par (n%2==0) ?

[...]



etc.


Voilà. Pour le reste, vu que je n'ai aucune regexp POSIX dans mes
quelques rares scripts, je ne suis pas intéressé pour moi-même. Mais
encore une fois merci pour ceux qui sont dans le même cas que toi, en
espérant que mes quelques remarques pourront leur être utiles si jamais
ils n'avaient pas les mêmes habitudes de programmation que toi.

Cordialement,
--
Olivier Miakinen
Avatar
Jean-Francois Ortolo
Bonjour Monsieur

Voir mes réponses ci-dessous.

Merci beaucoup pour votre réponse.

Bien à vous.

Amicalement.

Jean-François Ortolo


Le 14/01/2010 02:09, Olivier Miakinen a écrit :
Bonjour Jean-François,

Je n'ai lu que ça, et même que la fonction change() de ce script. Je
n'en ai eu le courage que parce que tu as abondamment commenté ce code,
ce dont je te remercie.

-----------------------------------------------------------

p=split(param, tableau, "");



Attention, ceci n'est pas portable : c'est un gnuisme (code spécifique
gnu). Sur les versions de awk différentes de gawk, rien ne dit comment
on doit traiter le cas où le 3e paramètre de split() est une chaîne
vide.




Effectivement, je ne savais pas cela.

Au départ, je sélectionnais les caractères de la chaîne param avec la
fonction substr(), mais je me suis aperçu qu'elle ne prenait pas laes
voyelles accentuées ( en ascii, pas en utf-8, je n'ai pas essayé pour
l'utf-8 ).


# Initialisation
# du premier paramètre
# de la fonction pcre.
chaine=""/".";



Il m'a fallu quelques secondes pour comprendre cette ligne.
Personnellement j'aurais écrit :
chaine = '"/" . ';




Effectivement avec des quotes simples ça marche aussi. Et
effectivement c'est mieux de mettre un espace avant et après le point.
Merci d'avoir corrigé. ;)

Au fait, il y a ici une supposition implicite, à savoir que la regexp
posix ne contient jamais aucun caractère « / », aussi bien écrit de
façon littérale que caché dans une variable.




J'ai surtout supposé, que tous les caractères "/" étaient échappés
dans la regexp.

for(i=1; i<=p; i++)
{
t=tableau[i];

if(t=="$")
{
quote_trouve=0;

# On suppose que les variables
# sont toujours accolées
# aux autres expressions,
# par un point, et que
# leurs noms ne contiennent pas
# de point.



Ceci est une autre supposition qui correspond certainement à ton propre
code, mais pas forcément aux code des autres (il suffit de voir comme tu
n'as mis aucune espace dans la ligne qui suit alors que moi j'en aurais
mis exactement onze !)



Pardon.

Il me semble, que le point est la seule possibilité d'opérateur de
concaténation en php. La juxtaposition pure n'est pas conforme à la
syntaxe de php, et déclenche une erreur de parsing. ( J'ai testé sur mon
ordinateur en php 5.2.11 ). D'autre part les noms de variables ne
doivent pas par définition contenir de point, sinon c'est considéré
comme une concaténation avec ce qui suit.

Et puis, comment pourrait-il y avoir des espaces dans des noms de
variables ? Voici ce qui figure dans le PHP Manual :

"Un nom de variable valide doit commencer par une lettre ou un
souligné (_), suivi de lettres, chiffres ou soulignés."



while((i<=p)&&(t!=".")&&(t!=","))
{
# Pas d'espace
# dans un nom de variable.
if((t!=" ")&&(t!="t"))
chaine=chaine t;



... et si jamais le code d'origine avait le mauvais goût de contenir des
espaces après un nom de variable, elles seront impitoyablement virées
par la transformation ! ;-)




S'il y a un ou des espaces à la fin du nom de variable, il seront
accolés à la fin du nom de la variable, donc copiage fidèle de
l'original, aucun problème ?

Je ne sais pas très bien ce qui se passe si l'on essaye d'ajouter un
espace contenu dans une variable, en fin de variable :

t=' ';
chaine="abc";

chaine=chaine t;
chaine= chaine "def";

A ce moment-là, chaine contient : "abc def" ou "abcdef" ?

Dans le premier cas mon code est juste, cependant je ne sais pas ce
qui se passe lors de l'exécution du code dans le deuxième cas.


i++;
t=tableau[i];
}

if(i>p)
{
# Fin de tableau[i]
# rencontré, sans
# atteindre la fin
# de l'expression rationnelle,
# donc erreur.
print "Erreur: expression rationnelle sur plusieurs lignes: " param
" " chaine> "/dev/stderr";



Sauf erreur, «> &2 » me semble plus portable que «> /dev/stderr ».
Mais je peux me tromper.




Peut-être pour Windows ? ;)

[...]
else if((t=="t")||(t=="c"))
{
if(t=="t")
{
# début de trim(
pattern="trim";
}
else
{
# Début de chr(
pattern="chr";
}



Ok, ceci est un code très spécifique à tes propres habitudes, mais vu
que c'est bien documenté il doit être facile de rajouter d'autres
fonctions selon les besoins de chacun.




Je reconnais, que le problème est la reconnaissance du pattern du nom
de la fonction incluse, ce qui nécessite du traitement complémentaire si
plusieurs noms de fonctions possibles commencent avec la même lettre.


w=split(pattern, tab, "");



Même gnuisme que signalé plus haut.


[...]
else if((t==""")||(t=="'"))
{
chaine=chaine t;

# Mémorisation du type de quote
# ( double ou simple )
# encadrant l'expression
# rationnelle.
s=t;

i++;
t=tableau[i];
while((i<=p)&&(quote_trouve==0))
{
if(t=="")
{
n++;
}



J'avoue que je n'ai pas compris le traitement des « » :
- pourquoi tu comptes le nombre de tous les successifs au lieu de les
recopier dans 'chaine' dès que tu en as deux d'affilée ;



Je pourrais, effectivement, mais mon procédé revient au même.

- comment tu gères les $, " et '.


>

J'ai besoin de savoir combien il y a d'échappements successifs, avant
un caractère différent de "".

Si ce nombre est pair, le caractère suivant n'est pas échappé, et il
faut l'échapper quand même dans la regexp modifiée, dans certains cas.

Pour le cas des $, " et ', ces caractères sont échappés au départ
comme à l'arrivée, donc il n'est pas nécessaire de faire un traitement
particulier d'échappement.


else
{
for(x=1; x<=n; x++)
chaine=chaine "";

q=n;

indic=0;
# Echappement
# au cas où.
if((n>0)&&((2*int(q/2.0))==n)&&((t=="&")||(t=="+")||(t==s)))



Est-ce que le test ((2*int(q/2.0))==n) ne pourrait pas être remplacé
tout simplement par (n%2==0) ?




Effectivement, je n'y avais pas pensé, parfois je ne sais pas ce qui
me passe par la tête... ;(

[...]



etc.


Voilà. Pour le reste, vu que je n'ai aucune regexp POSIX dans mes
quelques rares scripts, je ne suis pas intéressé pour moi-même. Mais
encore une fois merci pour ceux qui sont dans le même cas que toi, en
espérant que mes quelques remarques pourront leur être utiles si jamais
ils n'avaient pas les mêmes habitudes de programmation que toi.

Cordialement,



J'ajoute :

Après le code qui suit, il faut rajouter quote_trouve=0; , car dans
ce cas, cette variable est différente de 0, ce qui impacterait les
analyses ultérieures dans la même fonction, des sous-regexp chaînes de
caractères.

while((i<=p)&&(quote_trouve==0))
{

# Code...

}

quote_trouve=0;


D'autre part, il est bon pour simplifier, de réduire les deux
fonctions change(param) et change_i(param), à une seule fonction
change(param, chaine_fin)

chaine_fin sera le deuxième paramètre d'appel à change(), qui sera la
chaîne de caractère à rajouter en fin de regexp, donc ' . "/"' pour
change(), et ' . "/i"' pour change_i().

Donc, dans le corps principal de filtre.awk, on remplacera les appels
à ces deux fonctions par :

v=change(u, ' . "/"'); au lieu de v=change(u); , et

v=change(u, ' . "/i"'); au lieu de v=change_i(u);


Dans la fonction change(param, chaine_fin) , on remplacera ces
instructions :

chaine=chaine "."/",";

chaine=chaine "."/i",";

par :

chaine= chaine chaine_fin ",";

vers la fin de la fonction change()


Compte tenu des modifications de Monsieur Miakinen, il n'yaurait plus
qu'à trouver une alternative à p=split(param, tableau, ""); , pour
sélectionner chacun des caractères de param, associés à un indice i
allant de i=1 à i=length(param).

Il reste le problème du caractère "/" non échappé dans la regexp de
départ. A chaque fois que je programme ( seulement avec des regexp posix
jusqu'à présent ), je me pose la question : Faut-il ou non échapper "/"
? Je croyais qu'il était obligatoire d'échapper ce caractère, mais
peut-être me suis-je trompé... A ce moment-là, je pense que je n'aurais
pas d'autre solution, que de choisir un autre caractère de début et fin
de regexp, dont je sois sûr qu'il n'apparaît jamais dans les regexp.
Problème insoluble ?

En tout cas, Monsieur Miakinen, je vous suis très très reconnaissant
d'avoir indiqué les erreurs dans ce code, car je vais prochainement
tester sur un autre serveur, la migration de mon site partenaire
www.lescourses.com , et si ça ne marche paaaasss... le dirlo ne sera
poas content ;)

Avec mes respects.

Bien à vous.

Amicalement.

Jean-François Ortolo

--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.

Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Avatar
Jean-Francois Ortolo
Le 14/01/2010 12:12, Jean-Francois Ortolo a écrit :
Bonjour Monsieur


-----------------------------------------------------------

p=split(param, tableau, "");



Attention, ceci n'est pas portable : c'est un gnuisme (code spécifique
gnu). Sur les versions de awk différentes de gawk, rien ne dit comment
on doit traiter le cas où le 3e paramètre de split() est une chaîne
vide.




Effectivement, je ne savais pas cela.

Au départ, je sélectionnais les caractères de la chaîne param avec la
fonction substr(), mais je me suis aperçu qu'elle ne prenait pas laes
voyelles accentuées ( en ascii, pas en utf-8, je n'ai pas essayé pour
l'utf-8 ).




Je vous demande pardon, j'ai fait un lapsus linguae. ;)

Ce n'était effectivement pas la fonction substr() que j'ai essayé
d'utiliser, mais la fonction sub(). Celle-ci ne prenait pas les voyelles
accentuées. Je ne sais pas quelle fonction prendre pour sélectionner un
par un tous les caractères d'une chaîne ascii éventuellement étendu.


Au fait, il y a ici une supposition implicite, à savoir que la regexp
posix ne contient jamais aucun caractère « / », aussi bien écrit de
façon littérale que caché dans une variable.




J'ai surtout supposé, que tous les caractères "/" étaient échappés dans
la regexp.




Pour résoudre le problème du premier et du dernier caractère de la
regexp modifiée ( == standard pcre ), et pour éviter le cas où il y a
plusieurs caractères "/" "/" accolés, je pense que ce serait correct
d'utiliser le caractère dièze ( # ), et d'encadrer l'ensemble de la
regexp migrée ( sans les # de début et de fin ), par une fonction
preg_replace().

Cette fonction preg_replace évaluerait le contenu de la regexp après
migration ( == obtenue au moment du test final if(fin_trouve==1) ), et
qui remplace toutes les occurences de dièze précédés par un nombre x
pair ou nul de "", par x fois "" suivi de "#'. Cela revient à
échapper tous les dièzes qui ne le sont pas, et résoudrait le problème
de l'existence éventuelle de ce signe dièze dans la regexp.

Le seul problème, est que je ne sais pas comment faire un tel
remplacement avec preg_replace().

Merci beaucoup de votre réponse.

Bien à vous.

Amicalement.

Jean-François Ortolo

--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.

Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Avatar
Olivier Miakinen
Le 14/01/2010 15:17, Jean-Francois Ortolo a écrit :

Au départ, je sélectionnais les caractères de la chaîne param avec la
fonction substr(), mais je me suis aperçu qu'elle ne prenait pas laes
voyelles accentuées ( en ascii, pas en utf-8, je n'ai pas essayé pour
l'utf-8 ).



Je vous demande pardon, j'ai fait un lapsus linguae. ;)

Ce n'était effectivement pas la fonction substr() que j'ai essayé
d'utiliser, mais la fonction sub(). Celle-ci ne prenait pas les voyelles
accentuées. Je ne sais pas quelle fonction prendre pour sélectionner un
par un tous les caractères d'une chaîne ascii éventuellement étendu.



Pardon d'enfourcher l'un de mes chevaux de bataille favoris (quoique ça
fasse longtemps que je l'ai laissé tranquille), mais une chaîne ASCII ne
*peut* pas contenir de caractères accentués, et « ASCII étendu » ne veut
rien dire.

Plus précisément, cela peut valoir dire trop de choses différentes.
Parmi les extensions d'ASCII il y a des jeux de caractères 7 bits
dans lesquels certains caractères sont remplacés par d'autres (par
exemple "{|}" par "éùè"), il y a aussi des jeux de caractères 8 bits
parmi lesquels ISO-8859-1, CP1252 ou MacRoman, mais il y a aussi
UTF-8 (qui contrairement au premier que j'ai cité est 100 % compatible
ascendant avec ASCII).

Au fait, il y a ici une supposition implicite, à savoir que la regexp
posix ne contient jamais aucun caractère « / », aussi bien écrit de
façon littérale que caché dans une variable.



J'ai surtout supposé, que tous les caractères "/" étaient échappés dans
la regexp.





D'accord, c'est certainement de ma faute car je n'ai pas compris comment
tu traitais vraiment les au sein d'une regexp.

Pour résoudre le problème du premier et du dernier caractère de la
regexp modifiée ( == standard pcre ), et pour éviter le cas où il y a
plusieurs caractères "/" "/" accolés, je pense que ce serait correct
d'utiliser le caractère dièze ( # ), et d'encadrer l'ensemble de la
regexp migrée ( sans les # de début et de fin ), par une fonction
preg_replace().

Cette fonction preg_replace évaluerait le contenu de la regexp après
migration ( == obtenue au moment du test final if(fin_trouve==1) ), et
qui remplace toutes les occurences de dièze précédés par un nombre x
pair ou nul de "", par x fois "" suivi de "#'. Cela revient à
échapper tous les dièzes qui ne le sont pas, et résoudrait le problème
de l'existence éventuelle de ce signe dièze dans la regexp.



Dans ce cas, tu peux aussi bien le faire avec / qu'avec # (qui risque
d'ailleurs peut-être de se trouver plus facilement non échappé que /).
Un autre problème est que tout caractère peut aussi bien être caché
dans une variable.

Le seul problème, est que je ne sais pas comment faire un tel
remplacement avec preg_replace().



Je viens de te répondre dans fclr. Au passage, je vois que tu as vu
aussi l'autre problème que je te signale.

À mon humble avis, tu peux juste limiter les risques en choisissant un
caractère moins courant qu'un caractère ASCII, par exemple ¦ (pas |) ou
bien Ð (pas D).

Cordialement,
--
Olivier Miakinen
Avatar
Jean-Francois Ortolo
Le 14/01/2010 15:17, Jean-Francois Ortolo a écrit :

Pour résoudre le problème du premier et du dernier caractère de la
regexp modifiée ( == standard pcre ), et pour éviter le cas où il y a
plusieurs caractères "/" "/" accolés, je pense que ce serait correct
d'utiliser le caractère dièze ( # ), et d'encadrer l'ensemble de la
regexp migrée ( sans les # de début et de fin ), par une fonction
preg_replace().

Cette fonction preg_replace évaluerait le contenu de la regexp après
migration ( == obtenue au moment du test final if(fin_trouve==1) ), et
qui remplace toutes les occurences de dièze précédés par un nombre x
pair ou nul de "", par x fois "" suivi de "#'. Cela revient à
échapper tous les dièzes qui ne le sont pas, et résoudrait le problème
de l'existence éventuelle de ce signe dièze dans la regexp.

Le seul problème, est que je ne sais pas comment faire un tel
remplacement avec preg_replace().




Ca ne marcherait pas.

Essentiellement, car la regexp pcre utilisée dans cette fonction
preg_replace, serait soumise à la même limitation que précédemment dans
le choix du caractère délimiteur.

Le problème est, que l'on peut évaluer les caractères existants dans
une chaîne constante de caractères, mais pas dans une variable php.

Le problème résiduel, consisterait donc à trouver un caractère
délimiteur dont on sache au départ, qu'il n'appartient à aucune des
regexp à migrer ( avec ou sans variables php intégrées ).

Problème conjoncturel donc, et qui ne peut pas être automatisable.

Il va donc falloir, que je loggue tous les scripts php où
apparaissent au moins une variable php dans le premier paramètre des
fonctions à migrer, et que je regarde dans chacun de ce scripts, quel
serait le meilleur caractère délimiteur, qui n'apparaisse dans aucune de
ces variables.

Conclusion, du pain sur la planche en perspective... ;)

Mais... Je peux éventuellement logguer aussi toutes les variables php
associées à ces scripts php, et faire du traitement répétitif
d'affichage de toutes les lignes de ces scripts, où elles apparaissent,
ce qui me donnera toutes les instructions d'affectation de ces variables.

De l'à peu près, quoi... ;)

Bien à vous.

Amicalement.

Jean-François Ortolo

--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.

Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Avatar
Olivier Miakinen
Le 14/01/2010 18:28, Jean-Francois Ortolo a écrit :

Le problème résiduel, consisterait donc à trouver un caractère
délimiteur dont on sache au départ, qu'il n'appartient à aucune des
regexp à migrer ( avec ou sans variables php intégrées ).



grep "©" $(find . -name "*.php")

... et si tu trouves ne serait-ce qu'un seul ©, tu essayes avec ß,
avec ®, avec ÿ, et ainsi de suite jusqu'à en trouver un qui ne se
trouve utilisé nulle part !
Avatar
Jean-Francois Ortolo
Le 14/01/2010 18:28, Olivier Miakinen a écrit :

Pardon d'enfourcher l'un de mes chevaux de bataille favoris (quoique ça
fasse longtemps que je l'ai laissé tranquille), mais une chaîne ASCII ne
*peut* pas contenir de caractères accentués, et « ASCII étendu » ne veut
rien dire.

Plus précisément, cela peut valoir dire trop de choses différentes.
Parmi les extensions d'ASCII il y a des jeux de caractères 7 bits
dans lesquels certains caractères sont remplacés par d'autres (par
exemple "{|}" par "éùè"), il y a aussi des jeux de caractères 8 bits
parmi lesquels ISO-8859-1, CP1252 ou MacRoman, mais il y a aussi
UTF-8 (qui contrairement au premier que j'ai cité est 100 % compatible
ascendant avec ASCII).




Bonsoir Monsieur

Dans mon cas c'est très simple.

J'utilise vi comme éditeur, que j'ai configuré pour convertir en mode
latin1 en lecture et écriture, en éditant le fichier de configuration
/etc/vimrc

Le mode latin1 est ce que je désigne par "ascii étendu", c'est
probablement ce que vous appelez iso-8859-1, car du diable si je sais
comment générer le caractère euro avec mon clavier... ;(

Le problème du caractère délimiteur est résolu en ce qui me concerne,
car dans toutes les variables servant de regexp aux fonctions à migrer,
tous les caractères "/" sont échappés. Ce caractère "/" peut donc
service de délimiteur.

Merci beaucoup beaucoup pour vos réponses.

Bien à vous.

Amicalement.

Jean-François Ortolo

--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.

Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Avatar
Jean-Francois Ortolo
Le 14/01/2010 18:28, Olivier Miakinen a écrit :
Le 14/01/2010 15:17, Jean-Francois Ortolo a écrit :

J'ai surtout supposé, que tous les caractères "/" étaient échappés dans
la regexp.





D'accord, c'est certainement de ma faute car je n'ai pas compris comment
tu traitais vraiment les au sein d'une regexp.



À mon humble avis, tu peux juste limiter les risques en choisissant un
caractère moins courant qu'un caractère ASCII, par exemple ¦ (pas |) ou
bien Ð (pas D).

Cordialement,




Finalement...

J'ai loggué dans un fichier, tous les scripts et les variables (
chaque fichier sur une seule ligne ) où des variables apparaissent dans
les regexp des fonctions à migrer, et puis j'ai fait des cat répétitifs
à partir de ce fichier de log, des fichiers correspondants, en ne
sélectionnant que les lignes où apparaissent ces variables, avec un
script en Bourne Shell. Le résultat a été placé dans un autre fichier de
logs tmp.txt, dont j'ai fait un 'cat tmp.txt | egrep -e "/" > logs.txt'
dans un autre script Shell, pour sélectionner uniquement les lignes
comportant des caractères "/", pour voir si ce caractère est toujours
échappé dans les affectations à ces variables. Ensuite j'ai éliminé les
lignes commençant par / , car c'étaient les chemins absolus des
fichiers, pour ne laisser que les variables.

Il se trouve que dans toutes les variables apparaissant comme premier
paramètre dans ces fonctions à migrer, le caractère "/" est toujours
échappé par "".

Donc, ce caractère "/" peut servir ce caractère délimiteur, en tenant
compte du fait que, pour les regexp ou sous-regexp constantes chaînes de
caractères des fonctions à migrer, le caractère délimiteur doit toujours
être échappé, ce pourquoi j'ai fait une petite modification dans le
script filtre.awk

Le problème est donc résolu, mon site partenaire ( sa copie sur mon
ordinateur ) a été migré ce soir sans erreur.

Et puis j'ai corrigé une petite erreur, où j'échappais aussi les
quotes simples ou doubles de fin des sous-regexp constantes avant
migration. Maintenant tout est correct.

Merci beaucoup Monsieur, pour vos réponses et encouragements.

Bien à vous.

Amicalement.

Jean-François Ortolo

--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.

Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Avatar
Christophe Bachmann
Le 14/01/2010 20:45, Jean-Francois Ortolo a écrit :
Le 14/01/2010 18:28, Olivier Miakinen a écrit :






Bonsoir Monsieur

Dans mon cas c'est très simple.

J'utilise vi comme éditeur, que j'ai configuré pour convertir en mode
latin1 en lecture et écriture, en éditant le fichier de configuration
/etc/vimrc

Le mode latin1 est ce que je désigne par "ascii étendu", c'est
probablement ce que vous appelez iso-8859-1, car du diable si je sais
comment générer le caractère euro avec mon clavier... ;(



L'euro n'apparaît pas dans le jeu iso-8859-1 (latin 1) mais dans le
iso-8859-15 (latin 9) auquel cas il est disponible par <AltGr>+E ou
<Ctrl>+<Alt>+E (au moins sous windows)

Voir http://www.cs.tut.fi/~jkorpela/latin9.html (en anglais)
--
Greetings, Salutations,
Guiraud Belissen, Château du Ciel, Drachenwald,
Chris CII, Rennes, France
1 2 3