Try this:
ro='roundn(' # roundn open
rc=',n)' # roundn close
fun='exp\('
expression='exp(49/200)+(x-49/200)'
echo "$expression" |
perl -pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g; s/$fun[^)]*/$ro\$&/g"
which should give you:
roundn(exp(roundn(49/200,n)),n)+(x-roundn(49/200,n))
Your longer expression should result in:
roundn(exp(roundn(49/200,n)),n)+roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))+roundn(1/2,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^2+roundn(1/6,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^3+roundn(1/24,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^4+roundn(1/120,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^5+roundn(1/720,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^6+roundn(1/5040,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^7+roundn(1/40320,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^8+roundn(1/362880,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^9+roundn(1/3628800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^10+roundn(1/39916800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n)
^11
Explanation
/exp\([^)]*\K\)/)$rc/g
- close exp(), add roundn close
- for strings that start with "exp(" and end with ")"
\K
makes the "exp(" a zero-width match so only the closing paren is replaced
s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g
- strings of digits with mult and div, surround with roundn open and roundn close
- strings of digits that don't start with "^" but may contain "/" or "*"
- must be two or more total characters - there's probably a better way to do this
- carat is negative look-behind (zero-width) so it's not included when the replacement is made
s/exp\([^)]*/$ro\$&/g
- open exp(), add roundn open
- before "exp(" followed by zero or more characters that are not ")", add roundn open
$ro
, $rc
and $fun
are shell variables
- wrapping the Perl script in double quotes allows these variables to be expanded
$&
contains the entire match except for the zero-width portions
- escaping it is probably not necessary, but I did it just in case - to keep from confusing the shell
It wouldn't be too hard to make this work if there are more than one function. However, it will probably completely fall apart if they are nested.
Edit:
Here is a Perl script version:
$ro = "roundn(";
$rc = ",n)";
$fun = "exp\\(";
while (<>) {
s/$fun[^)]*\K\)/)$rc/g;
s/(?<!\^)[0-9\/*]+[0-9]/$ro$&$rc/g;
s/$fun[^)]*/$ro$&/g;
print
}
Run it like this:
perl script.pl < data.txt
Does anyone know a solution for this question based on batch (windows shell)? – Peterstone – 2010-11-23T09:11:04.103
@Dennis: freak! :) – akira – 2010-11-23T14:37:04.537
@Peterstone: Perl is available for Windows. The Windows batch language is not capable of this and I doubt that Powershell is by itself. You could probably do it in Python which is also available for Windows. @akira: Thanks! – Paused until further notice. – 2010-11-23T15:19:00.500
@Dennis: Well, I suppose I can download the strawberry perl... – Peterstone – 2010-11-23T17:24:55.410
@Dennis: Do you think I could do it with strawberry perl? – Peterstone – 2010-11-23T17:25:30.760
@Peterstone: Yes. – Paused until further notice. – 2010-11-23T17:40:03.187
@Peterstone: Try the Perl script I added. – Paused until further notice. – 2010-11-23T18:27:09.760