OVH Cloud OVH Cloud

expressions regulieres

7 réponses
Avatar
Cbc
Bonjour,

j'ai un morceau de fichier TeX de la forme suivante :

\item [...]
\item [...]
\begin{itemize}
\item [...]
\item [...]
\end{itemize}
\item [...]

je voudrais remplacer "\item[...]" par "<li>[...]</li>", mais seulement
pour ceux situés entre \begin{itemize} et \end{itemize} (le 3e et le 4e
ici) ! Comment faire?

Merci

7 réponses

Avatar
Olivier Miakinen

j'ai un morceau de fichier TeX de la forme suivante :

item [...]
item [...]
begin{itemize}
item [...]
item [...]
end{itemize}
item [...]

je voudrais remplacer "item[...]" par "<li>[...]</li>", mais seulement
pour ceux situés entre begin{itemize} et end{itemize} (le 3e et le 4e
ici) ! Comment faire?


Il y a plein de méthodes possibles. En voici trois.

La plus simple, très facile à réaliser si ton fichier est vraiment
organisé en lignes comme ceci, c'est de lire le fichier ligne par ligne
avec fgets(), et de ne faire les remplacements par preg_replace()
qu'après avoir lu le begin, tant que tu n'as pas lu le end.

La plus compliquée, c'est avec une superbe expression rationnelle PCRE
bardée d'assertions. Ne compte pas sur moi pour te l'écrire.

Une intermédiaire consiste à utiliser preg_replace_callback(). Une
première expression recherche la chaîne qui commence par le begin et
finit par le end, et la sous-chaîne trouvée est passée à la fonction de
callback qui elle-même remplace les items par des <li>.

Choisis celle que tu préfères... ou une autre !

Avatar
Cbc
Il y a plein de méthodes possibles. En voici trois.

La plus simple, très facile à réaliser si ton fichier est vraiment
organisé en lignes comme ceci, c'est de lire le fichier ligne par ligne
avec fgets(), et de ne faire les remplacements par preg_replace()
qu'après avoir lu le begin, tant que tu n'as pas lu le end.


Le problème, c'est qu'il y a des item qui sont sur plusieurs lignes
donc ça complique un peu...

La plus compliquée, c'est avec une superbe expression rationnelle PCRE
bardée d'assertions. Ne compte pas sur moi pour te l'écrire.


Ouais, sur moi non plus !

Une intermédiaire consiste à utiliser preg_replace_callback(). Une
première expression recherche la chaîne qui commence par le begin et
finit par le end, et la sous-chaîne trouvée est passée à la fonction de
callback qui elle-même remplace les items par des <li>.


Je vais essayer cette méthode je crois...
Pour écrire l'expression qui recherche la chaîne qui commence par le
begin et finit par le end : comment faire?
Je commence par @begin{itemize}()end{itemize}@, mais je mets
quoi au milieu, entre les parenthèses?

Merci

Avatar
David
On 26 Sep 2006 10:04:25 GMT, Cbc wrote:

Pour écrire l'expression qui recherche la chaîne qui commence par le
begin et finit par le end : comment faire?
Je commence par @begin{itemize}()end{itemize}@, mais je mets
quoi au milieu, entre les parenthèses?


ça, par exemple :
[^$]+


David

Avatar
Cbc
On 26 Sep 2006 10:04:25 GMT, Cbc wrote:

Pour écrire l'expression qui recherche la chaîne qui commence par le
begin et finit par le end : comment faire?
Je commence par @begin{itemize}()end{itemize}@, mais je mets
quoi au milieu, entre les parenthèses?


ça, par exemple :
[^$]+


Merci, mais ça n'a pas l'air de marcher quand il y a une succession de
plusieurs begin{itemize}...end{itemize} : il ne prend en compte que le
tout premier begin et le tout dernier end.
Il faudrait écrire quelque chose du genre ([^(end{itemize})]+) mais
ça ne marche pas...
Quelqu'un a une idée?

Merci


Avatar
Olivier Miakinen

Je vais essayer cette méthode je crois...
Pour écrire l'expression qui recherche la chaîne qui commence par le
begin et finit par le end : comment faire?
Je commence par @begin{itemize}()end{itemize}@, mais je mets
quoi au milieu, entre les parenthèses?


Le plus simple, c'est « .* ». Mais il te faut en plus des options de
recherche. D'abord l'option s (PCRE_DOTALL) puisque tu veux pouvoir
prendre les sauts de ligne. Et puis, à moins que tu n'aies qu'une seule
séquence begin ... end, tu dois inverser la tendance à la gourmandise
des expressions rationnelles au moyen de l'option U (PCRE_UNGREEDY).

Donc : '@begin{itemize}(.*)end{itemize}@sU'

Avatar
Olivier Miakinen

Merci, mais ça n'a pas l'air de marcher quand il y a une succession de
plusieurs begin{itemize}...end{itemize} : il ne prend en compte que le
tout premier begin et le tout dernier end.
Il faudrait écrire quelque chose du genre ([^(end{itemize})]+) mais
ça ne marche pas...
Quelqu'un a une idée?


Oui. Nos messages se sont croisés.

<cit. http://fr.php.net/manual/fr/reference.pcre.pattern.modifiers.php>
U (PCRE_UNGREEDY)
Cette option inverse la tendance à la gourmandise des expressions
rationnelles. Vous pouvez aussi inverser cette tendance au coup par coup
avec un ?. De même, si cette option est activée, le ? rendra gourmand
une séquence. Cette option n'est pas compatible avec Perl. Elle peut
aussi être mise dans le masque avec l'option ?U dans le pattern ou par
un point d'interrogation avant le quantifieur (.e.g. .*?).
</cit.>

Avatar
Cbc
Merci, mais ça n'a pas l'air de marcher quand il y a une succession de
plusieurs begin{itemize}...end{itemize} : il ne prend en compte que le
tout premier begin et le tout dernier end.
Il faudrait écrire quelque chose du genre ([^(end{itemize})]+) mais
ça ne marche pas...
Quelqu'un a une idée?


Oui. Nos messages se sont croisés.


Merci ça marche !