Discussion:
[HS] Expression reguliere
(trop ancien pour répondre)
Etienne SOBOLE
2008-07-10 23:56:48 UTC
Permalink
salut.

désolé de poser cette question ici, mais je sais pas ou la mettre

je cherche l'expression regulière qui compte un motif précis répété
succéssivement

genre j'ai la chaine
abcx2x2x2x2x2x2pq
je cherche a compte les motif x2

j'aimerai transformer cette chaine en
abc#6pq

indiquant pas la que j'ai 6 fois le motif recherché!

voila.
ca se fait ca avec une expression régulière ???

merci
Etienne
Olivier Miakinen
2008-07-11 00:32:17 UTC
Permalink
Post by Etienne SOBOLE
désolé de poser cette question ici, mais je sais pas ou la mettre
En l'absence d'un groupe consacré aux expressions régulières, ces
questions ont traditionnellement été acceptées dans ce groupe pourvu
qu'il s'agisse quand même de leur usage à travers PHP.
Post by Etienne SOBOLE
je cherche l'expression regulière qui compte un motif précis répété
succéssivement
genre j'ai la chaine
abcx2x2x2x2x2x2pq
je cherche a compte les motif x2
j'aimerai transformer cette chaine en
abc#6pq
indiquant pas la que j'ai 6 fois le motif recherché!
voila.
ca se fait ca avec une expression régulière ???
Il y a plusieurs méthodes possibles, utilisant selon le cas preg_match
ou preg_match_all + preg_replace, ou preg_replace seul, ou peut-être
preg_replace_callback.

Pour te répondre, je voudrais savoir d'abord :

1) Est-ce que le x2 peut se trouver à plusieurs endroits dans la chaîne,
et doit-il être traité à chaque fois ? Par exemple :
abcx2x2x2defx2x2pq -> abc#3defx2x2pq ou abc#3def#2pq ?

2) Dans le cas ci-dessus, est-il gênant de regrouper les comptes ?
abcx2x2x2defx2x2pq -> abc#5defpq

3) Y a-t-il des caractères ou des séquences de caractères que tu es sûr
de ne jamais rencontrer, et qui peuvent servir temporairement (y compris
par exemple le caractère #) ?

4) Est-ce que tu peux connaître une limite au nombre de x2 ?
Olivier Miakinen
2008-07-11 21:04:19 UTC
Permalink
En attendant une réponse d'Étienne, voici déjà une méthode pour le cas
le plus facile. Comme d'hab je n'ai pas testé, mais ça devrait se lire
assez facilement.
Post by Olivier Miakinen
Post by Etienne SOBOLE
genre j'ai la chaine
abcx2x2x2x2x2x2pq
je cherche a compte les motif x2
j'aimerai transformer cette chaine en
abc#6pq
4) Est-ce que tu peux connaître une limite au nombre de x2 ?
Mettons que cette limite soit un entier représenté par la constante
MAXREPLACE.

<?php
$array_pattern = new array();
$array_replace = new array();
$pattern = "";
for ($i = 1; $i <= MAXREPLACE; $i++) {
$pattern .= 'x2';
array_unshift($array_pattern, "/$pattern/");
array_unshift($array_replace, "#$i");
}

$result = preg_replace($array_pattern, $array_replace, $subject);
?>
Etienne SOBOLE
2008-07-12 10:55:54 UTC
Permalink
Post by Olivier Miakinen
En l'absence d'un groupe consacré aux expressions régulières, ces
questions ont traditionnellement été acceptées dans ce groupe pourvu
qu'il s'agisse quand même de leur usage à travers PHP.
ben c'est qu'a moitie lié au php.
En fait j'utilise json coté javascript et json_decode cote php.

le problème est que si en javascript j'ai un truc genre
var tData = [];
tData[5] = 10;

la serialisation json va me donner un truc genre

[null,null,null,null,null,10]

ce que je souhaite faire c'est remplacer ca par
[@N5_10]
afin de réduire le flot de données a envoyer.

Peut etre effectivement que dans le newsgroup javascript, ca aurai plus sa
place.
désolé.
Post by Olivier Miakinen
1) Est-ce que le x2 peut se trouver à plusieurs endroits dans la chaîne,
abcx2x2x2defx2x2pq -> abc#3defx2x2pq ou abc#3def#2pq ?
oui ca peut
Post by Olivier Miakinen
2) Dans le cas ci-dessus, est-il gênant de regrouper les comptes ?
abcx2x2x2defx2x2pq -> abc#5defpq
oui c'est génant ;)
Post by Olivier Miakinen
3) Y a-t-il des caractères ou des séquences de caractères que tu es sûr
de ne jamais rencontrer, et qui peuvent servir temporairement (y compris
par exemple le caractère #) ?
4) Est-ce que tu peux connaître une limite au nombre de x2 ?
non pas vraiement.

Etienne
Olivier Miakinen
2008-07-12 22:10:17 UTC
Permalink
Post by Etienne SOBOLE
Post by Olivier Miakinen
En l'absence d'un groupe consacré aux expressions régulières, ces
questions ont traditionnellement été acceptées dans ce groupe pourvu
qu'il s'agisse quand même de leur usage à travers PHP.
ben c'est qu'a moitie lié au php.
En fait j'utilise json coté javascript et json_decode cote php.
le problème est que si en javascript j'ai un truc genre
var tData = [];
tData[5] = 10;
la serialisation json va me donner un truc genre
[null,null,null,null,null,10]
D'accord. Pourquoi ne pas avoir parlé de "null," au lieu de "x2" ?
Post by Etienne SOBOLE
ce que je souhaite faire c'est remplacer ca par
afin de réduire le flot de données a envoyer.
C'était #5 au début et non @N5_ ! Bon, voici une proposition en PHP,
tu peux l'adapter pour y mettre les caractères que tu veux à la place
de '#'.
---------------------------------------------------------------------
<?php
header("Content-Type: text/plain");

function repnull($matches)
{
$count = strlen($matches[0]) / 5;
return '#' . $count . substr($matches[0], -1);
}
function dorepnull($subject)
{
return preg_replace_callback('/(?<=[[,])(null,)*null[],]/',
'repnull', $subject);
}
$a = '[null,null,null,null,null]';
$b = '[a,null,b,null,null,c,null,d]';
$c = '[nullard,annulle,null,tronull,"null",null,nul]';
echo $a . "\n-> " . dorepnull($a) . "\n";
echo $b . "\n-> " . dorepnull($b) . "\n";
echo $c . "\n-> " . dorepnull($c) . "\n";
?>
---------------------------------------------------------------------

Le résultat de l'exécution est :
---------------------------------------------------------------------
[null,null,null,null,null]
-> [#5]
[a,null,b,null,null,c,null,d]
-> [a,#1,b,#2,c,#1,d]
[nullard,annulle,null,tronull,"null",null,nul]
-> [nullard,annulle,#1,tronull,"null",#1,nul]
---------------------------------------------------------------------

S'il y en a que ça intéresse (toi ou quelqu'un d'autre) je peux
expliquer pourquoi ça marche.

Cordialement,
--
Olivier Miakinen
SAM
2008-07-13 07:21:12 UTC
Permalink
Post by Olivier Miakinen
Post by Etienne SOBOLE
le problème est que si en javascript j'ai un truc genre
var tData = [];
tData[5] = 10;
la serialisation json va me donner un truc genre
[null,null,null,null,null,10]
Alors en JS :

function compacter(tableau) {
var n = 0;
while(n<tableau.length && tableau[n]==null) n++;
return '@N'+n+'_'+tableau[n];
}
alert(compacter(tData));


Bon ... ça ne résoudra pas :
tData[5] = 'ab';
tData[15] = 'zx';
ni :
tData.length = 20;
tData[6] = 'fg';
Post by Olivier Miakinen
S'il y en a que ça intéresse (toi ou quelqu'un d'autre) je peux
expliquer pourquoi ça marche.
Ben moi, par exemple.
Et non seulement "pourquoi" mais "comment"

J'arrive bien à bidouiller un truc laborieux en JS(*) sans reg
expression, mais ... en PHP avec reg expression ... je nage.

d'abord :
que devient le $matches de repnull($matches)
dans dorepnull($subject) ?

Ensuite :
Mais où donc es-tu aller dénicher ce 'preg_replace_callback' ?
(doit quand même falloir fouiller pour trouver cette fonction !)

Je ne vois même pas la différence entre : 'preg_split' et 'explode' :-(
Post by Olivier Miakinen
$a = '[null,null,null,null,null]';
$b = '[a,null,b,null,null,c,null,d]';
$c = '[nullard,annulle,null,tronull,"null",null,nul]';
Et si tu as un bon moment tu pourras expliquer :
/(?<=[[,])(null,)*null[],]/
en particulier : [] (pourquoi ce n'est pas \[\] ?)
dans : *null[],]/ (comment l'expression repère les bons crochets ?)
mais aussi : (?<=[[,])


(*) à voir ici si on veut :
<http://cjoint.com/?hnbIeQxTmD>
J'étions parti du truc du genre :
abcx2x2x2x2x2x2pqx3x2zzbcx2x2x2x2xyz
et non pas d'un array
--
sm
Olivier Miakinen
2008-07-13 09:33:48 UTC
Permalink
Post by SAM
Post by Olivier Miakinen
S'il y en a que ça intéresse (toi ou quelqu'un d'autre) je peux
expliquer pourquoi ça marche.
Ben moi, par exemple.
Et non seulement "pourquoi" mais "comment"
Allons-y, et je vais commencer par l'expression régulière :
/(?<=[[,])(null,)*null[],]/

Tout d'abord, je suppose que tout le monde connaît les classes de
caractères, qui représentent toujours *un* caractère choisi parmi
plusieurs. Par exemple [0123456789] représente un chiffre de 0 à 9,
mais [0-9] représente la même chose. On voit que le caractère '-'
est spécial dans une classe de caractères, et si on veut l'inclure
il faut le mettre au début [-0-9] ou à la fin [0-9-]. Mais le
caractère ']' est spécial lui aussi ! Si on veut l'inclure, on ne
peut le mettre qu'au début : []0-9].

Ainsi, « [],] » est la classe de caractères qui représente soit un
crochet ']' soit une virgule ','. Quant à « [[,] », il représente
soit un crochet '[' soit une virgule ','.

Je ne ferai pas l'affront d'expliquer '*', et il peut rester un seul
truc un peu mystérieux : « (?<= <quelque chose> ) ». Il s'agit d'une
assertion positive arrière (positive lookbehind assertion) qui vérifie
que la chaîne en question se trouve bien avant celle que l'on veut
récupérer, mais sans la récupérer. Ainsi, (?<=,)null, trouvera bien
« null, » dans « ,null, » mais pas dans « ,tronull, ».

Au final, /(?<=[[,])(null,)*null[],]/ trouvera :
null,
null]
null,null,
null,null]
null,null,null,
null,null,null]
null,null,null,null,
null,null,null,null]
et ainsi de suite, mais *seulement* après une virgule ou un crochet ouvrant.

Vu que j'utilise preg_replace_callback, le résultat du match sera envoyé
à la fonction repnull, qui trouve le match complet dans $matches[0] et
le contenu d'éventuelles parenthèses captruantes dans $matches[1], etc.
(mais je ne m'en sers pas). Mettons qu'elle reçoive par exemple la
chaîne "null,null]", de longueur 10. Le nombre de null est 10/5 = 2,
calculé par :
$count = strlen($matches[0]) / 5;
Je rajoute '#' devant, et derrière je veux rajouter ',' ou ']' selon ce
qu'il y avait au départ, ce qui se fait par substr($matches[0], -1).
Dans ce cas précis :
'#' . $count . substr($matches[0], -1)
vaut :
'#' . 2 . ']'

Et voilà !
Post by SAM
que devient le $matches de repnull($matches)
dans dorepnull($subject) ?
Il est remplacé par la chaîne envoyée en retour de repnull(). Ainsi,
"null,null]" est remplacé par "#2]".
Post by SAM
Mais où donc es-tu aller dénicher ce 'preg_replace_callback' ?
(doit quand même falloir fouiller pour trouver cette fonction !)
La fouille n'est pas bien longue, car la doc est bien faite de ce point
de vue-là. Par exemple, sur la page <http://fr.php.net/preg_replace> tu
vois dans la colonne de gauche toutes les fonctions apparentées :
# preg_grep
# preg_last_error
# preg_match_all
# preg_match
# preg_quote
# preg_replace_callback
# preg_replace
# preg_split
Il suffit d'un clic pour visiter la doc de chacune.
Post by SAM
Je ne vois même pas la différence entre : 'preg_split' et 'explode' :-(
'explode' ne traite que des chaînes statiques, 'preg_split' des
expressions régulières. Je crois que JavaScript a une seule fonction
pour cela, mais c'est grace au fait qu'il existe un type RegExp, non ?
Post by SAM
/(?<=[[,])(null,)*null[],]/
en particulier : [] (pourquoi ce n'est pas \[\] ?)
Parce que je ne cherche pas une séquence de *quatre* caractères "[],]"
mais *un* seul caractère qui est soit "]" soit ",".
Post by SAM
dans : *null[],]/ (comment l'expression repère les bons crochets ?)
mais aussi : (?<=[[,])
Cf. les explications ci-dessus à propos des classes de caractères.

Cordialement,
--
Olivier Miakinen
Etienne SOBOLE
2008-07-13 10:42:03 UTC
Permalink
Post by SAM
function compacter(tableau) {
var n = 0;
while(n<tableau.length && tableau[n]==null) n++;
}
alert(compacter(tData));
Interessant,
mais j'ai opté pour une méthode plus global travaillant sur la chaine une
fois sérialisée, car la structure que je renvoi est trop complexe pour que
je m'amuse a chercher tous les tableaux ca donne.

var expr = /(null,)+/
var tRes = expr.exec(sDossier);
while (tRes)
{
var sDossier = sDossier.replace(expr, "@N" + (tRes[0].length /
tRes[1].length) + "@");
var tRes = expr.exec(sDossier);
}

et ca remplace une liste de null, par @Nx@
ou x ext les nombre de null, consecutif trouvé !

voila
A+
Etienne
Olivier Miakinen
2008-07-13 10:45:51 UTC
Permalink
Post by SAM
Mais où donc es-tu aller dénicher ce 'preg_replace_callback' ?
(doit quand même falloir fouiller pour trouver cette fonction !)
Tiens, il semblerait que ce soit possible en JavaScript aussi depuis la
version 1.3 :
http://developer.mozilla.org/fr/docs/R%C3%A9f%C3%A9rence_de_JavaScript_1.5_Core:Objets_globaux:String:replace#Exemple_:_utilisation_d.27une_fonction_inline_modifiant_les_caract.C3.A8res_trouv.C3.A9s

Donc :

sujet.replace('/(?<=[[,])(null,)*null[],]/',
function(match) {
count = strlen(match)/5;
last = match.substring(strlen(match)-1);
return '#' + count + last;
});

(non testé)

Je n'ai pas le temps de rappeler le contexte pour faire suivre dans
fr.comp.lang.javascript, mais ne pas hésiter à le faire s'il y a besoin
de poursuivre les recherches dans ce langage.
SAM
2008-07-13 17:41:08 UTC
Permalink
Post by Olivier Miakinen
Tiens, il semblerait que ce soit possible en JavaScript aussi depuis la
http://developer.mozilla.org/fr/docs/R%C3%A9f%C3%A9rence_de_JavaScript_1.5_Core:Objets_globaux:String:replace#Exemple_:_utilisation_d.27une_fonction_inline_modifiant_les_caract.C3.A8res_trouv.C3.A9s
sujet.replace('/(?<=[[,])(null,)*null[],]/',
function(match) {
count = strlen(match)/5;
last = match.substring(strlen(match)-1);
return '#' + count + last;
});
(non testé)
Je n'ai pas le temps de rappeler le contexte pour faire suivre dans
fr.comp.lang.javascript, mais ne pas hésiter à le faire s'il y a besoin
de poursuivre les recherches dans ce langage.
Comme ça ne fonctionne pas et en particulier la RegExp, je tente la
chose ...
(en essayant au mieux de mes possibilités bien réduites).
<487a23f8$0$915$***@news.orange.fr>
--
sm
Etienne SOBOLE
2008-07-13 10:42:03 UTC
Permalink
Post by Olivier Miakinen
D'accord. Pourquoi ne pas avoir parlé de "null," au lieu de "x2" ?
parce que il n'y a pas que les null, à remplacer...
j'ai pas voulu entrer dans un cas particulier.
Idem. c'etait pas encore vraiment défini ce que je voulais utiliser au
final.
Post by Olivier Miakinen
S'il y en a que ça intéresse (toi ou quelqu'un d'autre) je peux
expliquer pourquoi ça marche.
J'ai bien compris ton code.
Merci, c'est cool.

Mais pour être honete ma question originale portait sur les expressions
régulières.
Je voulais savoir si une expression pouvait faire le travail toute seule
sans l'aide d'un script.

D'un autre coté, la solution que tu donnes est tres bien.
je vais pas passer 15 jours a chercher :) sinon je suis pas l'à d'avoir fini

Merci
A bientot
Etienne
Continuer la lecture sur narkive:
Loading...