begin process at 2012 02 13 01:30:03
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Astuces

 > GENERATION DE L'EXPRESSION REGULIERE (REGEXP) POUR MANGER JUSQU'A UNE CHAINE

GENERATION DE L'EXPRESSION REGULIERE (REGEXP) POUR MANGER JUSQU'A UNE CHAINE


 Information sur la source

Note :
Aucune note
Catégorie :Astuces Classé sous :expression, régulière, regular, generation, tag Niveau :Initié Date de création :04/11/2007 Date de mise à jour :04/11/2007 12:16:56 Vu :6 346

Auteur : Zeroc00l

Ecrire un message privé
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (1)
Ajouter un commentaire et/ou une note


 Description

Bon je sais pas vous mais moi ça me gonfle de devoir écrire l'expression reguliere qui signifie : "manger jusqu'a" !

Exemple :
1) Vous souhaitez chercher une balise html
   <truc ... >
   Facile ! C'est "<[^>]*>"

2) Vous souhaitez chercher un commentaire en c++, php, ...
   /* commentaire [sur plusieurs lignes] */
   Heu attend je réfléchi ... arf galère

3) Vous souhaitez chercher des commentaires html
   <!-- ... -->
  Heu attend .. AU SECOUR !!!


Bon clairement ca devient vite infernal !
Donc le but de cette source est de générer la regexp qui va manger tout jusqu'à une chaine précise (la chaine est inclue dans le repas de la regexp :p)
Les expressions régulières requise pour les exemples ci-dessus s'écriront donc :
1) "<" + UNTIL_WITH(">");
2) "/\*" + UNTIL_WITH("*/");
2) "<!--" + UNTIL_WITH("-->");

Carrément plus simple non ? :)
Le code est un peu astucieux et faut réfléchir pour le comprendre ...
Bon je sais ... vous allez tous pomper le code et basta X-D !

La fonction UNTIL_WITH prend en argument une chaine normale,
les caractères spéciaux n'ont pas besoin d'être échappé.
Une variable static recense les caracteres qui seront echappé automatiquement.

Les autres variables static sont à modifier par vos soins !
(super rapide normalement si vous connaissez les regexp)

J'ai fait une autre fonction UNTILS_WITH (notez le 'S' à UNTIL) qui génère une regexp qui mange tout jusqu'à tomber sur une des deux chaines.
Exemple : UNTILS_WITH("fin", "end");
La fonction est EXTREMEMENT simple car elle utilise juste UNTIL_WITH !
En regardant la source vous pourrez faire une liste aussi longue que vous le souhaitez.

A noter enfin qu'au cas ou une chaine est prefixe d'une autre cela ne pose pas de probleme,
c'est la chaine la plus longue qui sera manger à la fin.

Source

  • #include <string>
  • #include <iostream>
  • using namespace std;
  • static const string to_escape = "^\\*+()[]{}$"; // Tous les caracteres qui ont besoin d'etre echapp?
  • static const char escape_char = '\\';
  • static const string parent_open = "(?:"; // Parenthese ouvrante non capturante pour ne pas gener les matchs, (en general "(?:")
  • static const char parent_close = ')';
  • static const char bracket_open = '[';
  • static const char bracket_close = ']'; // A placer au debut de classe d'intervalle
  • static const char bracket_not = '^'; // Parfois egal a '!'
  • typedef string (*func)(const string& word, int length);
  • // Echappe simplement les caracteres
  • // Contrainte : length >= 1 && word.length >= length
  • static string ESCAPE(const string& word, int length)
  • {
  • string res;
  • for (int i = 0; i < length; ++i)
  • {
  • if (string::npos != to_escape.find(word[i]))
  • res += escape_char;
  • res += word[i];
  • }
  • return res;
  • }
  • // Appelle ESCAPE
  • // ET ajoute une subtilit?
  • // Contrainte : <les memes que ESCAPE>
  • static string WITH(const string& word, int length)
  • {
  • string res = ESCAPE(word, length);
  • return res.insert(1 + (res[0] == escape_char), 1, '+'); // LA petite subtilit? :)
  • }
  • // Permet de construire une regexp qui mange tout et s'arrete apres une chaine donn?e
  • // Exemple pour matcher un commentaire en c++ : "/*" + UNTIL("*/") + "*/"
  • // Facile non ?
  • static string UNTIL_WITH(const string& word)
  • {
  • unsigned int n = word.length();
  • string res = n > 1 ? parent_open : "";
  • unsigned int i = 1;
  • while (i < word.length() && word[0] == word[i])
  • ++i;
  • func Subtility = i < word.length() ? WITH : ESCAPE;
  • // Optionnel, il s'agit d'un pronostic sur la taille probable
  • // Ce pronostic optimise un peu ...
  • // Le pronostic est inferieur ? la taille r?elle si des caract?res doivent etre echapp? !
  • // Comptons les caracteres ( n == word.length() )
  • // 1 : parenthese ouvrante
  • // n - 1 : Nombre de '|'
  • // n * 3 : Nombre de '[^]'
  • // n * 2 - 1 : Nombre de caracteres dans les crochets
  • // (n-1) * n / 2 + n -1 : Nombre de caracteres en dehors des crochets (somme de 0 a n - 1) et n-1 fois le '+'
  • // 1 + 1 : parenthese fermante et etoile
  • // n + 1 : Mot a manger a la fin avec le '+'
  • // Soit au final :
  • // {
  • res.reserve((15 + n) * n / 2 + 1);
  • // Version ou le pronostic >= taille reelle (considere que tous les caracteres ont besoin d'etre echapp?s) !
  • // res.reserve((n + 9) * n);
  • // }
  • for (i = 0; i < n; ++i)
  • {
  • if (i)
  • {
  • res += '|';
  • res += Subtility(word, i);
  • }
  • res += bracket_open;
  • res += bracket_not;
  • if (word[0] == word[i])
  • res += word[i];
  • else if (word[i] == bracket_close)
  • {
  • res += word[i];
  • res += word[0];
  • }
  • else
  • {
  • res += word[0];
  • res += word[i];
  • }
  • res += bracket_close;
  • }
  • if (n > 1)
  • res += parent_close;
  • res += '*' + Subtility(word, i);
  • return res;
  • }
  • // M?me chose que UNTIL mais pour s'arreter apres la premiere des deux chaines trouv?e
  • // Cette fonction est la fonction de base permetant de construire des listes de chaines devant lesquelles s'arreter.
  • // ( Certes UNTIL avec S n'existe pas mais tant pis :p )
  • static string UNTILS_WITH(const string& word_1, const string& word_2)
  • {
  • return parent_open + UNTIL_WITH(word_1) + "|" + UNTIL_WITH(word_2) + parent_close;
  • }
  • int main()
  • {
  • cout << "Commentaire C++, php ... :" << endl;
  • =>cout << "/\\*" + UNTIL_WITH("*/") << endl;
  • cout << endl;
  • cout << endl;
  • // Matcher un commentaire HTML selon la norme W3C
  • // format : <!-- blablabla -- blablabla >
  • // Et oui ! normalement -- et > ne sont pas forcement coll? :
  • cout << "Commentaire HTML (selon la norme W3C) :" << endl;
  • cout << "<!--" + UNTIL_WITH("--") + UNTIL_WITH(">") << endl;
  • cout << endl;
  • cout << endl;
  • cout << "jusqu'a \"abc\" :" << endl;
  • cout << UNTIL_WITH("abc") << endl;
  • cout << endl;
  • cout << endl;
  • return EXIT_SUCCESS;
  • }
#include <string>
#include <iostream>

using namespace std;

static const string to_escape   = "^\\*+()[]{}$"; // Tous les caracteres qui ont besoin d'etre echapp?
static const char   escape_char = '\\';
static const string parent_open   = "(?:"; // Parenthese ouvrante non capturante pour ne pas gener les matchs, (en general "(?:")
static const char   parent_close  = ')';
static const char   bracket_open  = '[';
static const char   bracket_close = ']'; // A placer au debut de classe d'intervalle
static const char   bracket_not   = '^'; // Parfois egal a '!'

typedef string (*func)(const string& word, int length);

// Echappe simplement les caracteres
// Contrainte : length >= 1 && word.length >= length

static string ESCAPE(const string& word, int length)
{
  string res;

  for (int i = 0; i < length; ++i)
  {
    if (string::npos != to_escape.find(word[i]))
      res += escape_char;
    res += word[i];
  }
  return res;
}

// Appelle ESCAPE
// ET ajoute une subtilit?
// Contrainte : <les memes que ESCAPE>
static string WITH(const string& word, int length)
{
  string res = ESCAPE(word, length);
  return res.insert(1 + (res[0] == escape_char), 1, '+'); // LA petite subtilit? :)
}

// Permet de construire une regexp qui mange tout et s'arrete apres une chaine donn?e
// Exemple pour matcher un commentaire en c++ : "/*" + UNTIL("*/") + "*/"
// Facile non ?
static string UNTIL_WITH(const string& word)
{
  unsigned int n = word.length();
  string res = n > 1 ? parent_open : "";
  unsigned int i = 1;

  while (i < word.length() && word[0] == word[i])
      ++i;
  func Subtility = i < word.length() ? WITH : ESCAPE;

  // Optionnel, il s'agit d'un pronostic sur la taille probable
  // Ce pronostic optimise un peu ...
  // Le pronostic est inferieur ? la taille r?elle si des caract?res doivent etre echapp? !
  // Comptons les caracteres ( n == word.length() )
  // 1 : parenthese ouvrante
  // n - 1 : Nombre de '|'
  // n * 3 : Nombre de '[^]'
  // n * 2 - 1 : Nombre de caracteres dans les crochets
  // (n-1) * n / 2 + n -1 : Nombre de caracteres en dehors des crochets (somme de 0 a n - 1) et n-1 fois le '+'
  // 1 + 1 : parenthese fermante et etoile
  // n + 1 : Mot a manger a la fin avec le '+'
  // Soit au final :
  // {
   res.reserve((15 + n) * n / 2 + 1);
  // Version ou le pronostic >= taille reelle (considere que tous les caracteres ont besoin d'etre echapp?s) !
  // res.reserve((n + 9) * n);
  // }

  for (i = 0; i < n; ++i)
  {
    if (i)
    {
      res += '|';
      res += Subtility(word, i);
    }
    res += bracket_open;
    res += bracket_not;
    if (word[0] == word[i])
      res += word[i];
    else if (word[i] == bracket_close)
    {
      res += word[i];
      res += word[0];
    }
    else
    {
      res += word[0];
      res += word[i];
    }
    res += bracket_close;
  }
  if (n > 1)
    res += parent_close;
  res += '*' + Subtility(word, i);
  return res;
}

// M?me chose que UNTIL mais pour s'arreter apres la premiere des deux chaines trouv?e
// Cette fonction est la fonction de base permetant de construire des listes de chaines devant lesquelles s'arreter.
// ( Certes UNTIL avec S n'existe pas mais tant pis :p )
static string UNTILS_WITH(const string& word_1, const string& word_2)
{
  return parent_open + UNTIL_WITH(word_1) + "|" + UNTIL_WITH(word_2) + parent_close;
}






int main()
{
  cout << "Commentaire C++, php ... :" << endl;
=>cout << "/\\*" + UNTIL_WITH("*/") << endl;
  cout << endl;
  cout << endl;

  // Matcher un commentaire HTML selon la norme W3C
  // format : <!-- blablabla -- blablabla >
  // Et oui ! normalement -- et > ne sont pas forcement coll? :
  cout << "Commentaire HTML (selon la norme W3C) :" << endl;
  cout << "<!--" + UNTIL_WITH("--") + UNTIL_WITH(">") << endl;
  cout << endl;
  cout << endl;

  cout << "jusqu'a \"abc\" :" << endl;
  cout << UNTIL_WITH("abc") << endl;
  cout << endl;
  cout << endl;

  return EXIT_SUCCESS;
}

 Conclusion

Si y'a des bug hésitez pas !
J'ai pas super testé la fonction UNTIL_WITH.
Juste dans ma tête et dans le main ...

La source est dans la catégorie "Astuce" et non pas "Chaine de caractère" ...
Ai-je bien fait ?


 Historique

04 novembre 2007 12:12:44 :
Retour en arriere apres prévisualisation. Je modifie un peu le texte et au moment de refaire la prévisualisation on me somme de mettre une explication sur la modif que j'ai faite... Faut-il envoyer un dictionnaire aux administrateurs pour Noël ? :-p
04 novembre 2007 12:16:56 :
Retour en arriere apres prévisualisation. Je modifie un peu le texte et au moment de refaire la prévisualisation on me somme de mettre une explication sur la modif que j'ai faite... Faut-il envoyer un dictionnaire aux administrateurs pour Noël ? :-p

 Sources du même auteur

Source avec Zip GESTION (OU SIMULATION) DES ÉVENEMENTS EN C++ PURE

 Sources de la même categorie

Source avec Zip SCHEDULER RR FIFO par yvesB87
Source avec Zip ALGORITHMES RÉCURSIFS VS ALGORITHMES ITÉRATIFS par yvesB87
Source avec Zip Source avec une capture C++ FORMAT D'IMAGE AVEC QT par pop70
Source avec une capture EXEMPLE DE POINTEURS DE FONCTION par pop70
Source avec Zip Source avec une capture [C++] CLASS REGISTER par Miwik

 Sources en rapport avec celle ci

CONVERSION DE FICHIER EN FICHIER BMP par seoseo
Source avec Zip Source avec une capture ÉVALUATEUR D'EXPRESSIONS BOOLÉENNES (BEE) par macsou01
Source avec Zip Source avec une capture EVALUATEUR_EXPRESSION_ARITHMETIQUE par Donald180v
Source avec Zip Source avec une capture ANALYSEUR LEXICAL par Donald180v
EVALUER UNE EXPRESSION MATHÉMATIQUE par begueradj

Commentaires et avis

Commentaire de Zeroc00l le 22/12/2007 18:18:36

Pas mal de visiteurs, pas de message !
:'(

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

expression régulière C [ par Digaboy ] BonjourJe souhaiterais faire des expressions régulières en C. J'ai appris les bases grâce à ce tutorielPar contre je n'arrive pas à compiler mon code Expression régulières [ par poiuytrez3 ] Bonjour,j'essaye de détecter une date au format DD/MM/YYYY grave à une expression régulière que j'ai toruvé ici :http://www.regular-expressions.info/r Expression régulière POSIX abondante [ par sebclick ] Bonjour,Je cherche à traiter un fichier XML par un programme C à l'aide d'expression régulière pour récupérer le texte contenu entre deux balises.Voic filtrer un string avec une regular expression [ par olivierroyo ] Bonjour je souhaiterai filtrer un string et enlever les caracteres non autorisés.Pour cela ma regle de triage est definie par une expression du style besoin d'aide pour une expression régulière [ par psgkiki ] Bonjour a tous, Je suis entrain de faire un lex et un yacc et je cale sur une expression régulière. Je veux qu'il me renvoi le mot clé IDF à chaque fo [BAR]help expression régulière en perl [ par samordi ] Bonjour, Je débute en programmation et découvre le langage perl. Je suis actuellement bloqué à cause d'une expression régulière que je n'arrive pas a parser une expression mathématique, de manière récursive ou itérative ? [ par mmaximum ] Bonjour, Je suis actuellement en train de programmer un petit CAS, qui devra tourné sur un système très réduit (calculatrice). J'ai déjà crée toute l Erreur de compilation(generation) [ par Dariush ] DariushBonjour tout le monde;J'ai téléchargé le visual C++ 2008 Expresse (sous vista).Lorsque je compile mon programmme , j'ai le message suivant:<fon Erreur de generation [ par wislam2007 ] Salut je compile mon code, tt ça se passe bien, par contre quand je fai t le generation du .exe ça me genere des erreurs comme ça: error LNK2001: unr Comment chercher un opérande central d'une expression arithmétique [ par kadermissoum ] Bonjour; J'ai l'expression arithmétique suivante : S = "((A+B)*(C-(D/E)))";     |-----| |-||---|     |-----| |---------|        PG       PD - Je vou


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,842 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales