Vous n'êtes pas identifié(e).

#1 23/06/2011 19:11:44

debutant_24
Membre

regexp_replace et sa regex

Bonjour, je suis nouveau et j'ai un problème avec la fonction regexp_replace :

je n'arrive pas à capturer une séquence précise au milieu d'une autre, dans le champs text "liste" de ma table "test".

voici le champs "liste" de la première occurrence, j'ai des données entre des balises et je cherche à remplacer le contenu de la deuxième balise contenue elle-même dans la balise <i74></i74> :

<i73><1>zzzz</1><2>bbbb</2><3>kkkk</3></i73>
<i74><1>aaaa</1><2>rrrr</2><3>mmmm</3></i74>
<i75><1>gggg</1><2>hhhh</2><3>xxxx</3></i75>

Je passe donc la requête suivante :

UPDATE test SET liste=regexp_replace(liste, '<i74>.*<2>(.*?)</2>.*</i74>', 'nnnn') WHERE id=1;

Normalement il devrait remplacer "rrrr" par "nnnn", mais à la place il efface toute la ligne <i74></i74> pour la remplacer par "nnnn". Il ne semble pas prendre en compte les parenthèses.

Pourtant, la même regex avec la requête suivante renvoie bien le contenu de la balise <2> dans <i74> :

SELECT SUBSTRING(liste FROM '<i74>.*<2>(.*?)</2>.*</i74>') FROM test WHERE id=1;

résultat : "rrrr"

Comment faire comprendre à postgresql que je souhaite remplacer seulement le contenu de la balise <2> dans <i74> ?

Si quelqu'un a une idée... merci pour votre soutien !

Hors ligne

#2 24/06/2011 10:05:07

gleu
Administrateur

Re : regexp_replace et sa regex

regexp_replace remplace l'intégralité de l'élément deux par l'élément trois à partir de l'élément un. Du coup, le troisième élément doit changer ainsi :

b1=# select regexp_replace('<i74><1>aaaa</1><2>rrrr</2><3>mmmm</3></i74>', '(<i74>.*<2>)(.*?)(</2>.*</i74>)', E'\\1nnnn\\3');
                regexp_replace                
----------------------------------------------
 <i74><1>aaaa</1><2>nnnn</2><3>mmmm</3></i74>
(1 row)

Guillaume.

Hors ligne

#3 24/06/2011 12:32:55

debutant_24
Membre

Re : regexp_replace et sa regex

Merci, ça marche maintenant !

Par contre, je suis pas sûr de comprendre la troisième partie :

, E'\\1nnnn\\3');

Je présume que le \1 se rapporte au bloc de la première parenthèse du 2me élément et le \3 au bloc de la troisième parenthèse.
les \ sont doublés \\ pour ne pas être mal interprétés.

Mais j'ignore ce que signifie le E, j'ai jamais vu ça.

Hors ligne

#4 24/06/2011 14:13:48

gleu
Administrateur

Re : regexp_replace et sa regex

C'est spécifique à PostgreSQL. Cela permet de lui dire qu'on veut qu'il gère les échappements comme \\.


Guillaume.

Hors ligne

#5 24/06/2011 16:51:19

debutant_24
Membre

Re : regexp_replace et sa regex

Ok merci ! smile

Hors ligne

Pied de page des forums