Expression régulière: Problème de compilation

Bonjour
J’ai une chaine que je veux modifier via une expression régulière mais la compilation qui fonctionne sur cplusplus.com plante sur Arduino.

#include <iostream>
#include <string>
#include <regex>

extern const std::string html_6 "      <input type=\"radio\" name=\"tensionMoteur\" value=\"220\"><label>220V</label>
&nbsp;
\n";

int main ()
{
  std::string s (html_6);
  std::regex e ("(Moteur\\\" value=\\\"220\\\")"); 

  // using string/c-string (3) version:
  std::cout << std::regex_replace (s,e,"Moteur\" value=\"220\" checked ");

 

  return 0;
}

Merci de votre aide.

Sans aller très loin, les librairies n’existe sans doute pas. Par exemple les chaînes sont reconnues d’emblée.

std::string le std c’est pas pour quand on n’a pas le #include ? Aucune importance, on n’en a pas besoin.

std::cout ça c’est pour envoyer vers l’écran par défaut. Mais sur arduino, il n’y a pas d’écran. On peut rajouter des boutons, des écrans… mais ce n’est pas un clavier par défaut, ni un écran normal.

main() est caché on ne la voit pas et on n’y a pas accès. Main appelle 2 fonctions setup() et loop() et si elles n’y sont pas, il y a une erreur de lien.

Il y a sûrement une bibliothèque pour les expressions régulières, mais son nom ne peut pas être regex

Il ne reste plus grand chose…

Bonjour
Excusez moi j’ai eu un petit pb de PC mais le message était parti.
Donc inspiré du code ci-dessus j’ai fait ceci transposé pour un l’ESP:

#include <ESP8266WebServer.h>
#include <Arduino.h>
#include <regex>
using namespace std;

#include "html.h"
#include "elmt_html.h"

......

extern const std::string html_10 = "      <input type=\"radio\" name=\"tensionMoteur\" value=\"220\"><label>220V</label>
&nbsp;
\n";

void formParamCharge (ESP8266WebServer& server, int tensionSecteur , float tensionMoteur )
{
  std::string formulaire ;
  formulaire  = html_1 ;
//  formulaire += icon ;
  formulaire += html_2 ; 
  formulaire += html_6 ;          //checked
  formulaire += html_8 ;
  formulaire += html_9 ;
  formulaire += script ;

  server.send(200, "text/html", String(formulaire.c_str()) );
  Serial.println("Page html envoyée formParamCharge");
//  Serial.println(formulaire);
  std::string str;
  str = "      <input type=\"radio\" name=\"tensionMoteur\" value=\"220\"><label>220V</label>
&nbsp;
\n";
  std::regex e ("(Moteur\\\" value=\\\"220\\\")");
  std::regex_replace(str,e,"Moteur\" value=\"220\" checked ");
  Serial.println(String(str.c_str()));
}

et j’ai l’erreur suivante:

no matching function for call to ‘regex_replace(std::string&, std::regex&, const char [29])’

et là je suis coincé.

Euh sérieusement

 String(formulaire.c_str())

vous n’avez pas assez de String comme cela ?

Pour remplacer un texte par un autre dans une String vous avez la méthode replace(), pas la peine d’aller chercher des regex pour cela.

Utiliser JSON et la bibliothèque associée pourrait aussi être judicieux pour échanger des données avec le navigateur

Désolé mais étant novice dans ce langage je ne connaissais pas cette fonction.
Donc j’ai quand même solutionné mon pb en ajoutant string devant la chaîne de remplacement.
Mes chaînes sont stockées dans un autre fichier sous forme de: extern const std::string …

std::regex_replace(str,pattern,string("Moteur\" value=\"220\" checked "));

mais du coups mon pb s’est déporté sur:

Serial.println(String str);
ou
server.send(200, "text/html", str );

Donc comment convertir un std::string str en String compatible aux arguments de server.

Merci

en regardant la doc de std::string vous verrez que vous pouvez appeler c_str() sur votre String. ça vous donne un const char* qui doit passez sans souci dans la fonction send()

Serial.println(str.c_str());
server.send(200, "text/html", str.c_str() );

N'utilisez que des std::string dans ce cas partout dans votre code, ne mélangez pas avec des String arduino...

Je l'avais essayé mais si à la compile ça passe, ça plante lors de l'appel de la page ou de la trace sur le moniteur.

postez tout le code modifié

Voici le code

#include <ESP8266WebServer.h>
#include <string>
#include <regex>
using namespace std;

#include "html.h"
#include "elmt_html.h"
 


//***********************************************************************************
//page html fréquence et rampe

void formParamFreq (ESP8266WebServer& server, int frequence , float rampe )
{
  std::string formulaire ;
  formulaire  = html_1 ;
//  formulaire += icon ;
  formulaire += html_2 ;
  formulaire += html_3 ; 
  formulaire += frequence ;
  formulaire += html_4 ;
  formulaire += rampe ;
  formulaire += html_5 ;
  formulaire += html_7 ;
  formulaire += html_9 ;
  formulaire += script ;
  
  server.send(200, "text/html", String(formulaire.c_str()) );
  Serial.println("Page html envoyée formParamFreq");
//  Serial.println(formulaire);
}

//***********************************************************************************
//page html caractéristiques charge


void formParamCharge (ESP8266WebServer& server, int tensionSecteur , float tensionMoteur )
{
  std::string formulaire ;
  formulaire  = html_1 ;
//  formulaire += icon ;
  formulaire += html_2 ; 
  formulaire += html_6 ;          //checked
  formulaire += html_8 ;
  formulaire += html_9 ;
  formulaire += script ;

  std::regex pattern ("(Moteur\\\" value=\\\"220\\\")"); 
  std::regex_replace(formulaire,pattern,string("Moteur\" value=\"220\" checked "));

  server.send(200, "text/html", formulaire.c_str() );
  Serial.println("Page html envoyée formParamCharge");

  //char* c = const_cast<char*>(formulaire.c_str());
  
  Serial.println(formulaire.c_str());
  
  //Serial.println(formulaire);
  //std::string str;
  //str = "      <input type=\"radio\" name=\"tensionMoteur\" value=\"220\"><label>220V</label>
&nbsp;
\n";
  //str = html_6;
  //std::regex pattern ("(Moteur\\\" value=\\\"220\\\")"); 
  //std::regex_replace(str,pattern,string("Moteur\" value=\"220\" checked "));
  //Serial.println( String(str.c_str()));
  
}

ainsi que le sketch

wifi.zip (11.5 KB)

Je pense que j'ai trouvé, l'origine du pb vient du patern qui n'est pas accepté, en ne mettant qu'une lettre tout refonctionne.
Dès que j'aurai défini le nouveau patern je le posterai.

qu'est-ce que vous cherchez à remplacer avec votre pattern ?

Bonjour
J'ai une page html avec des cases à cocher, les éléments cochés sont stockés en EEPROM. Donc si rappel de la page les éléments en mémoire devront être affichés.
J'avais 2 solution:
soit je découpai la page en #define que je reformai en y insérant mes paramètres cochés
soit j'utilisai les regex sur le texte pour y insérer mes paramètres cochés car le pattern comporte des caractères non alpha
soit j'utilise la méthode replace() mais je ne sais pas si elle accepte les guillemets et autres.

Donc pour le fun j'étais sur le regex je persiste et ça plante j'envisagerai autre chose.

Ou une troisième solution avec ajax

La page web reste toujours identique et contient un JavaScript qui demande à votre serveur un json avec les valeurs à afficher

Ça a l’avantage de ne pas rafraîchir la page web tout entière

J'y avais pensé, soit ajax et javascript ou javascript seul mais pour le fun je testais les regex. Donc le pb vient soit du compilateur soit ...

Voici un exemple de substitution avec des String et replace()

String html_3 = "<table border=\"border:1px solid black\" width=\"90%\" align=\"center\">\n" \
                "du blabla\n" \
                "********  <input type=\"button\" value=\"-\" id=\"d2\" />\n" \
                "encore du blabla\n" \
                "********  <input type=\"button\" value=\"+\" id=\"d1\" />\n" \
                "et encore plus de blabla";

void setup()
{
  Serial.begin(115200);
  Serial.println(F("------- TEST DE REPLACE ------"));

  String valueID1 = "COUCOU ID1";;
  String valueID2 = "COUCOU ID2";

  String source = html_3;
  String aRemplacer;
  String substitution;

  aRemplacer = "+\" id=\"d1";
  substitution = valueID1 + "\" id=\"d1";
  source.replace(aRemplacer, substitution);

  aRemplacer  = "-\" id=\"d2";
  substitution  = valueID2 + "\" id=\"d2";
  source.replace(aRemplacer, substitution);

  Serial.println(source);
}

void loop() {}

le moniteur série (à 115200 bauds) affichera

[color=purple]
------- TEST DE REPLACE ------
<table border="border:1px solid black" width="90%" align="center">
du blabla
********  <input type="button" value="[color=red][b]COUCOU ID2[/b][/color]" id="d2" />
encore du blabla
********  <input type="button" value="[color=red][b]COUCOU ID1[/b][/color]" id="d1" />
et encore plus de blabla[/color]

Ok
merci pour ton attention

Autre information, dans la class d’autres méthodes ne fonctionnent pas comme to_string(int) après recherche il se pourrai que cela vienne du compilateur. donc je suis passé par la class

void formParamCharge (ESP8266WebServer& server, int tensionSecteur , int tensionMoteur )
{
  std::string formulaire ;
  formulaire  = html_1 ;
//  formulaire += icon ;
  formulaire += html_2 ; 
  formulaire += html_6 ;          //checked
  formulaire += html_8 ;
  formulaire += html_9 ;
  formulaire += scriptParam1 ;
  std::string js;
  std::stringstream ss;
  ss<<tensionSecteur;
  js = "function initVar() {\n coche('secteur";
  js += ss.str();;
  js += "','moteur";
  ss.str("");
  ss<<tensionMoteur;
  js += ss.str();
  js += "');}";
  formulaire += js ;
  formulaire += scriptParam2 ;
  formulaire += html_10 ;
  
  Serial.println(formulaire.c_str());
  server.send(200, "text/html", formulaire.c_str());
  Serial.println("Page html envoyée formParamCharge");
  
}

Je trouve que vous vous compliquez énormément la vie côté Arduino où on a peu de mémoire et peu de puissance de calcul...

Laissez le navigateur faire les modifications. Par exemple sauvez ce code HTML dans un fichier demo.htm sur votre PC et ouvrez le dans un navigateur web

<!DOCTYPE HTML>
<html lang='fr'>
<head>
 <meta charset='utf-8' />
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Démo JSON</title>
</head>
<script>
 const myData = {
 ID1:'COUCOU ID1',
 ID2:'COUCOU ID2',
 ID3:'COUCOU ID3'
 };

 function updateData() {Object.keys(myData).forEach(keyID => {document.getElementById(keyID).value = myData[keyID];});}
</script>
<body onload='updateData()'>
<input id='ID1' type="button" value=''>

<input id='ID2' type="button" value=''>

<input id='ID3' type="button" value=''>

</body>
</html>

Vous verrez que les 3 boutons ont leur texte qui aura été rempli dynamiquement.

b.png
Pour bâtir votre réponse vous avez 3 String.

La première est statique

[code]<!DOCTYPE HTML>
<html lang='fr'>
<head>
 <meta charset='utf-8' />
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Démo JSON</title>
</head>
<script>
 const myData = {

la deuxième est dynamique, ce que vous avez à générer dynamiquement c'est
ID1:'COUCOU ID1', ID2:'COUCOU ID2', ID3:'COUCOU ID3'ce qui peut se faire très simplement.

la troisième est statique

};

 function updateData() {Object.keys(myData).forEach(keyID => {document.getElementById(keyID).value = myData[keyID];});}
</script>
<body onload='updateData()'>
<input id='ID1' type="button" value=''>

<input id='ID2' type="button" value=''>

<input id='ID3' type="button" value=''>

</body>
</html>

En gros la page HTML aurait 3 parties, et la seule chose à générer ce sont les IDs à remplacer.

Ensuite à l'ouverture de la page par le navigateur, il se charge d'aller remplacer les valeurs aux bons endroits grace au petit script qui parcourt le tableau et va trouver les IDs dans la page pour remplacer leur valeur.

ça simplifierait bcp votre code...

en gros c'est comme on ferait en AJAX, sauf que vous embarquez les données sous forme de tableau dans la page web directement à la génération.

b.png

je crois que nous avons pensé à la même solution:

</head>
  <body onload="initVar()">
....

<form method="post" action="" >
....
corps de la page
....
</form>
 <script>
function initVar() {
 coche('secteur220','moteur110');}
  function coche (case1,case2) {
  document.getElementById(case1).checked = true; 
  document.getElementById(case2).checked = true;}
  </script>
  </body>
</html>

où ‘secteur220’ et ‘moteur110’ sont les id des btn radio, ce sont les seules parties générées par le code, le pb était de convertir un int en string que n’accepte pas la class d’où .
je ne peux pas faire plus simple.
par contre comme l’interface étant un smartphone je risque de devoir passer par un gestionnaire d’évènement js car il faut vraiment insister sur le bouton pour qu’il coche.
Merci