user70971: I have the following serial message that I'm receiving from an ESP32 running GRBL:
<Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc>

I want to check the value after SD: which in this case would be 0.21.
It is a value that represents the percentage of a file being read, so values between 100.00 and 0.00 are being sent.
My guess is to look for the SD: in the string and then read all characters until the , but I can't really find a way to realize that.
I found the startsWith() and the substring()function that are able to look for a set of characters in a string, but it seems like they can only check a set amount of characters which in this case doesn't work as 0.00 is 4 characters and 100.00 is 6 characters.
Any help is much appreciated!!

user4143: Firstly you should really be working with a C string (char *) instead of a String object, otherwise you will be massively fragmenting your heap with the string manipulations to come.
Once you have your data in a C string (char array) you can use strtok_r to split the string on the | character, then for each substring further split it on the :.  You need the _r variant of strtok to make it "re-entrant" so you can have two tokenizations at once nested.
For example (untested):
char *data = "<Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc>";
char *pair; // Pointer to a K/V pair
char *pairptr = data; // Pointer for outer strtok

// Split the string on the first |
pair = strtok_r(data, "|", &pairptr);

// While we have a K/V pair
while (pair) {
    char *kvptr = pair;
    // Split the substring into two parts on the colon
    char *key = strtok_r(pair, ":", &kvptr);
    char *val = strtok_r(NULL, ":", &kvptr);
    if (val) { // If we split the data correctly:
        if (strcmp(key, "SD") == 0) { // If the key is "SD" then
            Serial.print("SD data: ");
            Serial.println(val);
        }
    }
    // Get the next string portion
    pair = strtok_r(NULL, "|", &pairptr);
}

Once you have your val you can further split that down on commas in the same way as it's been split on the colon.

70971: <p>I have the following serial message that I'm receiving from an ESP32 running GRBL:</p>
<pre><code>&lt;Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc&gt;
</code></pre>
<p>I want to check the value after <code>SD:</code> which in this case would be <code>0.21</code>.
It is a value that represents the percentage of a file being read, so values between 100.00 and 0.00 are being sent.</p>
<p>My guess is to look for the <code>SD:</code> in the string and then read all characters until the <code>,</code> but I can't really find a way to realize that.</p>
<p>I found the <code>startsWith()</code> and the <code>substring()</code>function that are able to look for a set of characters in a string, but it seems like they can only check a set amount of characters which in this case doesn't work as <code>0.00</code> is 4 characters and <code>100.00</code> is 6 characters.</p>
<p>Any help is much appreciated!!</p>
 4143: <p>Firstly you should really be working with a C string (<code>char *</code>) instead of a <code>String</code> object, otherwise you will be massively fragmenting your heap with the string manipulations to come.</p>
<p>Once you have your data in a C string (char array) you can use <code>strtok_r</code> to split the string on the <code>|</code> character, then for each substring further split it on the <code>:</code>.  You need the <code>_r</code> variant of <code>strtok</code> to make it &quot;re-entrant&quot; so you can have two tokenizations at once nested.</p>
<p>For example (untested):</p>
<pre class="lang-cpp prettyprint-override"><code>char *data = &quot;&lt;Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc&gt;&quot;;
char *pair; // Pointer to a K/V pair
char *pairptr = data; // Pointer for outer strtok

// Split the string on the first |
pair = strtok_r(data, &quot;|&quot;, &amp;pairptr);

// While we have a K/V pair
while (pair) {
    char *kvptr = pair;
    // Split the substring into two parts on the colon
    char *key = strtok_r(pair, &quot;:&quot;, &amp;kvptr);
    char *val = strtok_r(NULL, &quot;:&quot;, &amp;kvptr);
    if (val) { // If we split the data correctly:
        if (strcmp(key, &quot;SD&quot;) == 0) { // If the key is &quot;SD&quot; then
            Serial.print(&quot;SD data: &quot;);
            Serial.println(val);
        }
    }
    // Get the next string portion
    pair = strtok_r(NULL, &quot;|&quot;, &amp;pairptr);
}
</code></pre>
<p>Once you have your <code>val</code> you can further split that down on commas in the same way as it's been split on the colon.</p>
