OVH Cloud OVH Cloud

Aide sur une expression régulière

4 réponses
Avatar
Vincent Ramos
Bonjour,

Je ne pense pas que ce forum soit le plus adapté pour ma question ; je n'en
trouve cependant pas d'autre : les expressions régulières ne sont propres à
aucun système d'exploitation ni à aucun langage. Si vous trouvez mieux,
merci de me rediriger.

Voici : je cherche à modifier toutes les occurrences de paires de guillemets
chiures de mouche, « " », par autre chose (disons « # ») dans des chaînes
contenant aussi des balises HTML. Or, il ne faut pas que le texte compris
dans les balises soit touché.

Exemple de chaîne possible :
<div id="bidule">Lorem ipsum "<a href="truc">dolor sit amet</a>", <span
class="machin">"consectetuer"</span> adipiscing elit. "Integer vehicula".
Pellentesque ultricies "porta" est. Maecenas blandit.</div>

Au final, j'aimerais :
<div id="bidule">Lorem ipsum #<a href="truc">dolor sit amet</a>#, <span
class="machin">#consectetuer#</span> adipiscing elit. #Integer vehicula#.
Pellentesque ultricies #porta# est. Maecenas blandit.</div>

J'ai essayé des dizaines de solutions, en vain. Le point de départ est
/"(.*?)"/ => '#$1#', avec quantificateur non avide.

Merci de votre éventuelle aide.

4 réponses

Avatar
Stephane Chazelas
2007-01-27, 13:56(+01), Vincent Ramos:
Bonjour,

Je ne pense pas que ce forum soit le plus adapté pour ma question ; je n'en
trouve cependant pas d'autre : les expressions régulières ne sont propres à
aucun système d'exploitation ni à aucun langage. Si vous trouvez mieux,
merci de me rediriger.


Par contre, il y a differentes sortes de regexp propres a tel ou
tel outil. Si tu veux des regexps de sed ou de awk, fcou est pas
mal. Si tu veux celles de vim, fce, celles de perl fclp sera
peut-etre mieux.

Mais personne ne t'en voudras pour poser une question sur les
regexps ici. Comme tu ne precises pas, je vais supposer que le
type de regexp n'importe pas.

Voici : je cherche à modifier toutes les occurrences de paires de guillemets
chiures de mouche, « " », par autre chose (disons « # ») dans des chaînes
contenant aussi des balises HTML. Or, il ne faut pas que le texte compris
dans les balises soit touché.
[...]

J'ai essayé des dizaines de solutions, en vain. Le point de départ est
/"(.*?)"/ => '#$1#', avec quantificateur non avide.
[...]


Ca, c'est des regexps perl ou PCRE (comme dans PHP) ou de TCL
recents... pas des regexps Unix dans le sens "standards" (BRE,
ERE) du terme.

Tu peux faire: s/((?:^|>)[^<]*)"/$1#/ mais ca ne te permettra
pas d'utiliser le "g" (de s/../../g).

Une approche:

{ sed 's/_/_u/g;s/,/_c/g;s/[<>]/,&/g' |
tr ',n' 'n,'
echo
} |
sed 's/"/#/g;n' |
tr -d 'n' |
tr , 'n' |
sed 's/_c/,/g;s/_u/_/g'

Ou avec perl:

perl -pe 's/(")|<.*?>|./$1?"#":$&/ge'

(dans les deux cas, on support que le fichier HTML est bien formé
(que les < ont leur > et qu'ils ne sont pas imbriqués) et on ne
prend pas en compte les commentaires (<!-- ... -->)...)

--
Stéphane

Avatar
Vincent Ramos
Stephane Chazelas a écrit une réponse complète et très utile.

Merci.
Avatar
DoMinix
Stephane Chazelas a écrit une réponse complète et très utile.

Merci.


comme d'hab, merci Stephane.

--
dominix

Avatar
Stephane Chazelas
2007-01-27, 13:30(+00), Stephane Chazelas:
[...]
Ou avec perl:

perl -pe 's/(")|<.*?>|./$1?"#":$&/ge'

(dans les deux cas, on support que le fichier HTML est bien formé
(que les < ont leur > et qu'ils ne sont pas imbriqués) et on ne
prend pas en compte les commentaires (<!-- ... -->)...)


Je pense que:

sed '/^([^<"]*(<[^>]*>)*)*"/{
s/(([^<"]*(<[^>]*>)*)*)"(([^<"]*(<[^>]*>)*)*)/1#4/g;}'

devrait marcher aussi.

Avec GNU sed (ERE).

sed -r '/^([^"<]|<[^>]*>)*/s/(([^"<]|<[^>]*>)*)"(([^"<]|<[^>]*>)*)/1#3/g'

--
Stéphane