Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Fusion d'expressions rationnelles

20 réponses
Avatar
Manu
Bonjour,

Connaissez vous un moyen (un outil) permettant de fusionner 2 ou
plusieurs expressions régulières en une unique expression ?
Théoriquement cela me semble possible, mais je ne suis pas un expert en
théorie des graphes/automates...
Le but est d'essayer de gagner en vitesse en élaborant une expression
compliquée plutôt que d'essayer de matcher consécutivement plusieurs
expressions.

L'idée est peut-être saugrenue ceci dit :)

10 réponses

1 2
Avatar
DINH Viêt Hoà

Connaissez vous un moyen (un outil) permettant de fusionner 2 ou
plusieurs expressions régulières en une unique expression ?
Théoriquement cela me semble possible, mais je ne suis pas un expert en
théorie des graphes/automates...
Le but est d'essayer de gagner en vitesse en élaborant une expression
compliquée plutôt que d'essayer de matcher consécutivement plusieurs
expressions.

L'idée est peut-être saugrenue ceci dit :)


oui, parce que les interpréteurs de regexp le font sans doute déjà pour
toi.

donc avec a et b

nouvelle_exp = a|b

--
DINH V. Hoa,

"Il faut savoir arrêter l'alcool de temps en temps" -- MAB

Avatar
Vincent Lascaux
oui, parce que les interpréteurs de regexp le font sans doute déjà pour
toi.

donc avec a et b

nouvelle_exp = a|b


Je me demande si Manu voulait pas parler d'une définition type
A = expression rationnelle
B = expression rationnelle qui utilise A

Exemple pour parser des URL (exemple comme ca, l'expression rationnelle que
j'écris est surement fausse) :
Mot = [^@: ]
Login = Mot:Mot@
URL = http://(Login)?(Mot/)+Mot?

A mon avis, on se rapproche pas mal des grammaire (même si lorsqu'il n'y a
pas de récursion, il doit toujours exister une expression rationnelle
équivalente).

--
Vincent

Avatar
DINH Viêt Hoà

Dans mon mail d'origine j'ai supprimé la phrase spécifiant que je
cherchais un truc "intelligent".
Cette solution je la connais, elle est bourrin et non optimale pour des
cas plus compliqués et quand les expressions sont nombreuses. Et je ne
pense pas que les moteurs de regexp fassent des optimisations si je
fournis quelquechose comme a|b|c (avec a, b, c étants des regexp).


ce que je te disais, c'est que c'est le moteur de regexp qui va en
général utiliser en interne une solution optimale quelque soit
l'expression que tu lui donnes.

--
DINH V. Hoa,

"Il faut savoir arrêter l'alcool de temps en temps" -- MAB

Avatar
Jym
On Mon, 14 Feb 2005, Manu wrote:

DINH Viêt Hoà wrote:

oui, parce que les interpréteurs de regexp le font sans doute déjà pour
toi.

donc avec a et b

nouvelle_exp = a|b


Dans mon mail d'origine j'ai supprimé la phrase spécifiant que je
cherchais un truc "intelligent".
Cette solution je la connais, elle est bourrin et non optimale pour des
cas plus compliqués et quand les expressions sont nombreuses. Et je ne
pense pas que les moteurs de regexp fassent des optimisations si je
fournis quelquechose comme a|b|c (avec a, b, c étants des regexp).

par exemple pour:
regexp1 : toto[0-9]+
regexp2 : tata[0-9]+

Je préferais : (t[oa]){2}[0-9]+
Plutot que : toto[0-9]+|tata[0-9]+

En fait je n'ai que faire de l'expression finale "textuelle". Seul le
comportement m'importe.


Il n'existe pas vraiment de forme canonique pour les regexp.
Il en existe une pour les automates. (mais la conversion automates ->
regexp n'est pas vraiment fixée).

Transforme les regexp en automates. Trouve l'automate minimal.
Retransforme en regexp (en privilégiant telle ou telle écriture). Ça doit
tout être des algos polynomiaux (quadratique ?)
Les moteurs de regexp (grep,...) travaillent avec l'automate déterministe
minimal.

Hypocoristiquement,
Jym.


Avatar
Manu
DINH Viêt Hoà wrote:

oui, parce que les interpréteurs de regexp le font sans doute déjà pour
toi.

donc avec a et b

nouvelle_exp = a|b


Dans mon mail d'origine j'ai supprimé la phrase spécifiant que je
cherchais un truc "intelligent".
Cette solution je la connais, elle est bourrin et non optimale pour des
cas plus compliqués et quand les expressions sont nombreuses. Et je ne
pense pas que les moteurs de regexp fassent des optimisations si je
fournis quelquechose comme a|b|c (avec a, b, c étants des regexp).

par exemple pour:
regexp1 : toto[0-9]+
regexp2 : tata[0-9]+

Je préferais : (t[oa]){2}[0-9]+
Plutot que : toto[0-9]+|tata[0-9]+

En fait je n'ai que faire de l'expression finale "textuelle". Seul le
comportement m'importe.

PS: je sais que la première expression n'est pas totalement équivalente
mais c'est plus pour donner une idée.

Avatar
Jérémy JUST
On Mon, 14 Feb 2005 20:28:58 +0100
Manu wrote:

Le but est d'essayer de gagner en vitesse en élaborant une expression
compliquée plutôt que d'essayer de matcher consécutivement plusieurs
expressions.


Si j'ai bien compris, tu veux (entre autres) mettre en facteur les
chaînes communes à plusieurs motifs?


L'idée est peut-être saugrenue ceci dit :)


Non-non, elle est intéressante, et souvent évoquée. Mais la solution
va dépendre du dialecte de regexp, et va rarement être optimale à coup
sûr.

En Perl, par exemple, tu peux utiliser Regexp::Optimizer :
http://search.cpan.org/~dankogai/Regexp-Optimizer-0.15/
http://search.cpan.org/~dankogai/Regexp-Optimizer-0.15/lib/Regexp/Optimizer.pm

--
Jérémy JUST

Avatar
Nicolas Le Scouarnec
Le but est d'essayer de gagner en vitesse en élaborant une expression
compliquée plutôt que d'essayer de matcher consécutivement plusieurs
expressions.
Si j'ai bien compris, tu veux (entre autres) mettre en facteur les

chaînes communes à plusieurs motifs?


C'est pas plutot réaliser l'automate associé reconaissant l'union des
langages, le determiniser, le minimiser et retrouver l'expression
régulière associée a l'automate ? A la main, c'est vrai que c'est
"simple" mais fastidieux ...

L'idée est peut-être saugrenue ceci dit :)
Non-non, elle est intéressante, et souvent évoquée. Mais la solution

va dépendre du dialecte de regexp, et va rarement être optimale à coup
sûr.


Google est très avare de résultats quand on lui demande regexp minimal
determinist union ...


--
Nicolas Le Scouarnec


Avatar
Laurent Wacrenier
Manu écrit:
par exemple pour:
regexp1 : toto[0-9]+
regexp2 : tata[0-9]+

Je préferais : (t[oa]){2}[0-9]+
Plutot que : toto[0-9]+|tata[0-9]+


Plutôt

t(oto|ata)[0-9]+

C'est une factorisation. Vu qu'il existe des algorithmes pour faire
celà dans les arithmétiques polynomiale ou booleene, ça doit être
faisable dans l'arithmétique des expressions rationnelles.

Mais le résultat risque de dépendre de la forme des expressions
originelles. Si elles sont marquées

(to){2}[0-9]+
(ta){2}[0-9]+

Celà pourrait retourner

(to{2}|ta{2})[0-9]+

De toutes ces formes, en plus des alternatives simples, la plus
optimale dépend de l'implémentation car les alternatives coûtent cher.

PCRE par exemple peut optimiser ses expressions en sachant quelle est
la première lettre que doit avoir le motif et celle ci peut être plus
difficile à déterminée dans le cas d'une expression complexe.

Au passage, un optimiseur digne de ce nom pourrait remplacer le [0-9]+
final par un [0-9] simple si on n'a pas à travailler sur le motif
recherché.

Avatar
Jym
On Tue, 15 Feb 2005, Laurent Wacrenier wrote:

Manu écrit:
par exemple pour:
regexp1 : toto[0-9]+
regexp2 : tata[0-9]+

Je préferais : (t[oa]){2}[0-9]+
Plutot que : toto[0-9]+|tata[0-9]+


Plutôt

t(oto|ata)[0-9]+

C'est une factorisation. Vu qu'il existe des algorithmes pour faire
celà dans les arithmétiques polynomiale ou booleene, ça doit être
faisable dans l'arithmétique des expressions rationnelles.


Pas sur à 100% : les regexp n'ont pas de bonne spropriétés mathématiques
genre commutativité ou distributivité (enfin, ça dépend pour quelles
opérations). En plus, l'étoile doit vraiment foutre le bordel dans toute
tentative de factorisation.

Meme en se restreignant à la simple concaténation, on a un monoide libre
et plein d'indécidables de partout (à commencer par la correspondance de
Post, qui n'est pas vraiment reliée à la factorisation mais montre que la
non-commutativité engendre pas mal de trucs chiants).

Hypocoristiquement,
Jym.


Avatar
Manu
Laurent Wacrenier wrote:

Plutôt

t(oto|ata)[0-9]+

C'est une factorisation. Vu qu'il existe des algorithmes pour faire
celà dans les arithmétiques polynomiale ou booleene, ça doit être
faisable dans l'arithmétique des expressions rationnelles.


J'avais ajouté un postscriptum à mon message à cet effet...

PCRE par exemple peut optimiser ses expressions en sachant quelle est
la première lettre que doit avoir le motif et celle ci peut être plus
difficile à déterminée dans le cas d'une expression complexe.


Je vais voir l'API PCRE donc.

Au passage, un optimiseur digne de ce nom pourrait remplacer le [0-9]+
final par un [0-9] simple si on n'a pas à travailler sur le motif
recherché.


???

1 2