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

Trouver une chaine dans une "sous-regexp" ?

1 réponse
Avatar
t0rt0ise
Salut,

Je suis un peu perdu, j'ai pas vraiment d'idee comment resoudre un
petit probleme que l'on m'a pose.
Alors si quelqu'un veux bien me donner quelques conseils utiles...

Voila, je dois implementer une fonction qui prends deux parametres une
"courte" chaine de caractere et une regexp.
Elle doit rendre TRUE si la chaine ("courte") est valable dans uen
sous partie de la regexp.

par exemple:
si ma regexp c'est \dtoit\d et que ma chaine est "5t" ou "oi" ou
"it6"c OK sinon 33 ne marche pas...

Bon j'ai ecrit un petit truc mais je sais que c'est pas ca...

$regexp = shift or die;
$str1 = shift or die;
@arr = split ("", $regexp);

for ($i=0;$i<=($#arr-1);$i++) {
for ($j=$i;$j<=$#arr;$j++) {
$res = '';
for ($k=$i;$k<=$j;$k++) {
$res .= $arr[$k];
}
if (eval {$str1 =~ m/^$res$/}) {
print "YES!\n";
exit 0;
}
}
}
print "NO!\n";
exit 1;

Je vois deux "options algorithmique" un peu plus avancees:
1. Decomposer la regexp en 2 et faire un appel recursif (la coupure en
2 morceaux glissant le long de la regexp via une boucle)
2. rechercher dans la regexp la ou le premier caractere de la chaine
courte correspond et continuer la verification de la chaine courte sur
la regexp a partir de cette position.

J'avoue que je suis un peu dans le brouillard,

Merci pour votre aide !

t0rt0ise

1 réponse

Avatar
jl_morel
Dans l'article <86132a29-b770-4aac-9471-
, a dit...

Voila, je dois implementer une fonction qui prends deux parametres une
"courte" chaine de caractere et une regexp.
Elle doit rendre TRUE si la chaine ("courte") est valable dans uen
sous partie de la regexp.

par exemple:
si ma regexp c'est dtoitd et que ma chaine est "5t" ou "oi" ou
"it6"c OK sinon 33 ne marche pas...

Bon j'ai ecrit un petit truc mais je sais que c'est pas ca...

$regexp = shift or die;
$str1 = shift or die;
@arr = split ("", $regexp);

for ($i=0;$i<=($#arr-1);$i++) {
for ($j=$i;$j<=$#arr;$j++) {
$res = '';
for ($k=$i;$k<=$j;$k++) {
$res .= $arr[$k];
}
if (eval {$str1 =~ m/^$res$/}) {
print "YES!n";
exit 0;
}
}
}
print "NO!n";
exit 1;



Si j'ai bien compris, vous essayez de découper la regexp pour tester avec
votre chaîne. Le problème c'est que la regexp ne peut pas être découpée en
caractères avec split.

Le plus simple est peut-être d'utiliser le module Regexp::Genex qui est
capable de générer des chaînes qui correspondent avec une regexp; dans une
chaîne qui correspond, on peut alors placer votre chaîne à tester dans
toutes les positions depuis le début et tester à chaque fois avec la
regexp. Si ça "match", bingo : votre chaîne est reconnue par une partie de
la regexp.

Pas très claire l'explication ? voila le code proposé :

#!/usr/bin/perl
use strict;
use warnings;
use Regexp::Genex 'strings';

my $r = shift or die;
my $s = shift or die;

my @good = strings($r) or die "Bad regexp";

foreach my $good (@good) {
for ( my $i = 0; $i <= length($good) - length($s); $i++ ) {
my $t = $good;
substr( $t, $i, length $s ) = $s;
if ( $t =~ m/$r/ ) {
print "YES!n";
exit 0;
}
}
}
print "NO!n";
exit 1;

__END__

Attention le module Regexp::Genex a des limitations, voir la doc.

HTH

--
J-L.M.
http://www.bribes.org/perl