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)?

11 ビュー (過去 30 日間)
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

採用された回答

Star Strider
Star Strider 2022 年 10 月 6 日
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 件のコメント
Tomazz
Tomazz 2022 年 10 月 6 日
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.
Star Strider
Star Strider 2022 年 10 月 6 日
As always, my pleasure!

サインインしてコメントする。

その他の回答 (1 件)

Steven Lord
Steven Lord 2022 年 10 月 6 日
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 件のコメント
Tomazz
Tomazz 2022 年 10 月 6 日
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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCharacters and Strings についてさらに検索

製品


リリース

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by