Azzera filtri
Azzera filtri

How to evaluate numeric expression in a string, which contains "12u" (for 12e-6) and "0.1m" (for 0.1e-3) formated numbers (standing for micro and milli)?

3 visualizzazioni (ultimi 30 giorni)
Hi,
I'd like to have a "supercharged" eval function, which would accept expressions where numbers can be given with 'm' (mili) or 'u' (micro extension.
Here is my naive approach is to define function seval
seval("1m") % works fine
ans = 1.0000e-03
seval(['10*(0.2m+20*3.1u)']) % works fine
ans = 0.0026
seval('max(1u,2m)') % errors, since 'm' in 'max' is also replaced
Error using solution>seval
Invalid expression. Check for missing multiplication operator, missing or unbalanced delimiters, or other syntax error. To construct matrices, use brackets instead of parentheses.
function rez = seval(s)
s = strrep(s, 'u', 'e-6'); % micro
s = strrep(s, 'm', 'e-3'); % mili
s = strrep(s, 's', 'e-0'); % :-)
rez = eval(s);
end
This works fine for simple expressions, but obviously not for
seval('max(1u,2m)')
So, I'd like to replace 'm' with 'e-3', but only when 'm' follows a well formated number. Seems like a job for regexp, but I couldn't find an elegant way to solve this.
P.S. Bonus question:
I'd also like to use 'variables'. A way to acieve this is to replace e.g. '1+a' with '1+var(a)', but only when 'a' is "standalone factor" in the expression. Any ideas?
seval2('1m + a') % this would translate to ...
seval('1m + var(a)')
function rez = var(s) % an example of 'variable' function
switch s
case 'a'
rez =1;
case('b')
rez = 2;
otherwise
rez = 0;
end
end

Risposta accettata

Star Strider
Star Strider il 6 Ott 2022
Here is my regexprep attempt at ‘seval’
str = 'max(1u,2m)';
out = seval(str)
out = 'max(1e-6,2e-3)'
str = 'max(1.5u,2.01m)';
out = seval(str)
out = 'max(1.5e-6,2.01e-3)'
function res = seval(s)
res = s;
res = regexprep(res, '(?<=\d)m','e-3');
res = regexprep(res, '(?<=\d)u','e-6');
res = regexprep(res, '(?<=\d)s','e-0');
end
The ‘Bonus question’ eludes me, likely because I am not confident that I understand it.
.
  3 Commenti
Tomazz
Tomazz il 6 Ott 2022
Thank you, your first solution is perfect for what I needed. I knew there had to be a nice hack for that.
It seems I didn't state the bonus question clearly enough, but it is less difficult to solve, anyway.
Of course you are both right that my approach is not the best in a general case, but for limited and specialized requirements, your first solution works great.
Also thank you for pointing out that str2func can be used this way. I was not aware of that.

Accedi per commentare.

Più risposte (1)

Steven Lord
Steven Lord il 6 Ott 2022
I'd like to have a "supercharged" eval function
This doesn't sound like a good idea.
which would accept expressions where numbers can be given with 'm' (mili) or 'u' (micro extension.
I strongly recommend that instead of making a "supercharged" version of eval that you think smaller. A function that accepts a string or char vector containing a number followed by a suffix then:
  1. splits the text into the number part and the suffix part
  2. converts the number part to an actual double value then
  3. multiplies the double value by a scaling factor determined from the suffix
would be more focused and less likely to get you into trouble. The splitting may be a bit tricky, since the "number part" may contain digits, a decimal point, perhaps an arithmetic symbol, and potentially the letters 'd', 'e', 'i', and/or 'j'.
x = 1.23e-1+2i
x = 0.1230 + 2.0000i
  1 Commento
Tomazz
Tomazz il 6 Ott 2022
Thank you for comments. I know my hack is a bad practice and won't work in a general case.
However, my requirements are more specialized and limited, and I don't need to process every kind of allowed number format, just simple “1.2m”, “exp(-3m*10)”, so Star's solution works perfectly for me.

Accedi per commentare.

Categorie

Scopri di più su Characters and Strings in Help Center e File Exchange

Prodotti


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by