ESP32 Regex search for all iterations

0

I am using Bluetooth and receiving a CSS gradient string like this:

(90deg, rgba(66, 68, 90, 1) 0%,rgba(72, 79, 164, 1) 100%)

I am using regex to pull out the "90" for the angle:

regex r_dir("([0-9]{2,3}deg)");
smatch m_dir;

regex_search(data, m_dir, r_dir);
string temp = m_dir[0].str();
        
int dir = atoi(temp.replace(temp.find("deg"), 3, "").c_str());

This works fine and I am able to get "90". I also need to pull out the colours (and their percentage). Unfortunately there is not built in function to return all matches in a string so I used an example I found online:

regex r_col("(rgba\\(([0-9]{1,3}(, |,|)){4}\\) [0-9]{1,3}%)");

sregex_iterator iter(data.begin(), data.end(), r_col);
sregex_iterator end;

while(iter != end)
{
    Serial.println("fff");

    for(unsigned i = 0; i < iter->size(); ++i)
    {
        Serial.println( (*iter)[i].str().c_str());
    }
    //Serial.println((*iter)[0].str().c_str());
    ++iter;
}

However not only does this not work, but it causes a crash on my ESP:

Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (Btc_task)
Core 0 register dump:
PC      : 0x400d38af  PS      : 0x00060e36  A0      : 0x800d399d  A1      : 0x3ffcd5f0  
A2      : 0x3ffcf110  A3      : 0x00000001  A4      : 0x3ffe1218  A5      : 0x3ffe53f4  
A6      : 0x3ffc5868  A7      : 0x3ffe0e5f  A8      : 0x3ffe0e5e  A9      : 0x3f401aa4  
A10     : 0x3ffcf110  A11     : 0x00000001  A12     : 0x0000007f  A13     : 0x3ffe5354  
A14     : 0x3ffc5868  A15     : 0x00000000  SAR     : 0x00000010  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff  

Backtrace: 0x400d38af:0x3ffcd5f0 0x400d399a:0x3ffcd660 0x400d399a:0x3ffcd6d0 0x400d3b6d:0x3ffcd740 0x400d3856:0x3ffcd760 0x400d399a:0x3ffcd7d0 0x400d3b6d:0x3ffcd840 0x400d3856:0x3ffcd860 0x400d399a:0x3ffcd8d0 0x400d399a:0x3ffcd940 0x400d399a:0x3ffcd9b0 0x400d38cd:0x3ffcda20 0x400d38cd:0x3ffcda90 0x400d3ac1:0x3ffcdb00 0x400d3899:0x3ffcdb70 0x400d3ac1:0x3ffcdbe0 0x400d399a:0x3ffcdc50 0x400d3899:0x3ffcdcc0 0x400d38cd:0x3ffcdd30 0x400d38cd:0x3ffcdda0 0x400d399a:0x3ffcde10 0x400d399a:0x3ffcde80 0x400d3a69:0x3ffcdef0 0x400d3a69:0x3ffcdf60 0x400d3899:0x3ffcdfd0 0x400d399a:0x3ffce040 0x400d3b6d:0x3ffce0b0 0x400d3856:0x3ffce0d0 0x400d399a:0x3ffce140 0x400d3b6d:0x3ffce1b0 0x400d3856:0x3ffce1d0 0x400d399a:0x3ffce240 0x400d3899:0x3ffce2b0 0x400d38cd:0x3ffce320 0x400d38cd:0x3ffce390 0x400d399a:0x3ffce400 0x400d399a:0x3ffce470 0x400d3a69:0x3ffce4e0 0x400d3a69:0x3ffce550 0x400d3899:0x3ffce5c0 0x400d3ac1:0x3ffce630 0x400d399a:0x3ffce6a0 0x400d3b6d:0x3ffce710 0x400d3856:0x3ffce730 0x400d399a:0x3ffce7a0 0x400d3899:0x3ffce810 0x400d38cd:0x3ffce880 0x400d38cd:0x3ffce8f0 0x400d399a:0x3ffce960 0x400d399a:0x3ffce9d0 0x400d3a69:0x3ffcea40

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5828
entry 0x400806ac

This is caused by (*iter)[i] although I don't know why. I found this GitHub issue on it but that's about it.

I've tried Regexp, specifically the example on iterating over a string. The example caused my ESP to crash however this example I found on an SO post causes no crash it just finds no matches:

ms.Target ((char *)data.c_str());
unsigned int count = ms.MatchCount ("(rgba\\(([0-9]{1,3}(, |,|)){4}\\) [0-9]{1,3}%)");

Serial.print ("Found ");
Serial.print (count);
Serial.println (" matches.");
for (int j = 0; j < count; j++)
{
    Serial.print ("Capture number: ");
    Serial.println (j, DEC);
    Serial.print ("Text: '");
    Serial.print (ms.GetCapture ((char *)data.c_str(), j));
    Serial.println ("'");
}

with the output being:

Found 0 matches.

Does anyone know to match all occurrences on an ESP?

c++
regex
esp32

1 Answer

0

When using prototyping boards there is a through back of limited memory, moreover C is also limited to core dependencies.

I've fire up my NodeMcu board with ESP32 to test your approach.

Just use a simpler way of substring() to take directly the value from your string.

Instead of using regex use the following substring() -once your css doesn't change its key attributes but only values-. Then you can store the result inside variables and make your logic.

#include <iostream>       // std::cout

int main ()
{
  std::string css ("(90deg, rgba(66, 68, 90, 1) 0%,rgba(72, 79, 164, 1) 100%)");
 
    std::cout << "DEG: " <<  css.substr(1,2) << '\n';
  
  return 0;
} 

Give it a try!

answered on Stack Overflow Dec 31, 2020 by George Gotsidis

User contributions licensed under CC BY-SA 3.0