On ne peut malheureusement pas faire appel au DOM dans ce cas précis car pour lui, dans la chaîne test, le CDATA c'est:
<![CDATA[ retetette rpoep <![CDATA[ contenue à conserver ]]>
(La première balise ouvrante et la première fermante).
En partant du principe qu'il n'y a qu'un niveau d'imbrication, tu peux faire ça:
1 2 3 4 5 6 7 8 9 10 11 12 13
| let test ="blabla <![CDATA[ retetette rpoep <![CDATA[ contenue à conserver ]]> roeporp eopo ]]> blabla";
//let test ="blabla <![CDATA[ retetette rpoep <![CDATA[ contenue à conserver ]]> roep <![CDATA[ contenue à conserver ]]> roeporp eopo ]]> blabla";
let previousLength;
let newLength;
do {
previousLength = test.length;
test = test.replace(/(<!\[CDATA\[[^\]<]*(?:<(?!!\[CDATA\[)[^\]<]*|](?!]>)[^\]<]*)*)<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
newLength = test.length;
} while(newLength < previousLength);
console.log(test); // blabla <![CDATA[ retetette rpoep contenue à conserver roeporp eopo ]]> blabla |
La boucle do ... while permet de traiter les cas où un CDATA en contient plusieurs autres. (car le remplacement les enlève un par un).
Détail de la pattern:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ( # groupe de capture 1
<!\[CDATA\[
[^\]<]* # tout ce qui n'est pas un ] ou <
(?:
< (?! !\[CDATA\[ ) # un < qui n'est pas le début d'une balise ouvrante
[^\]<]*
|
] (?!]>) # un ] qui n'est pas le début d'une balise fermante
[^\]<]*
)*
)
<!\[CDATA\[
( [\s\S]*? ) # groupe de capture 2
]]> |
S'il y a plus d'un niveau d'imbrication, alors il faut changer la pattern en
/(<!\[CDATA\[[^\]<]*(?:<(?!!\[CDATA\[)[^\]<]*|](?!]>)[^\]<]*)*)<!\[CDATA\[([^\]<]*(?:<(?!!\[CDATA\[)[^\]<]*|](?!]>)[^\]<]*)*)]]>/g
Bien entendu tout ceci ne sera fonctionnel qu'à la condition qu'il n'y ait aucune balise CDATA ouvrante ou fermante qui soit orpheline.
Partager