필터 지우기
필터 지우기

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 (최근 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.

댓글을 달려면 로그인하십시오.

추가 답변 (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 CenterFile Exchange에서 Characters and Strings에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by