# String manipulation of type String substitution in mathematical expression

Imagine something like

``````exp(49/200)+(x-49/200)
``````

I want to pass as argument of the function "roundn" whatever operation that is not an addtion or a subtraction So my expresion became

``````roundn(exp(roundn(49/200,n)),n)+(x - roundn(49/200,n)
``````

Well the expression I want to manipulate is this:

``````exp(49/200)+exp(49/200)*(x-49/200)+1/2*exp(49/200)*(x-49/200)^2+1/6*exp(49/200)*(x-       49/200)^3+1/24*exp(49/200)*(x-49/200)^4+1/120*exp(49/200)*(x-49/200)^5+1/720*exp(49/200)*(x-49/200)^6+1/5040*exp(49/200)*(x-49/200)^7+1/40320*exp(49/200)*(x-49/200)^8+1/362880*exp(49/200)*(x-49/200)^9+1/3628800*exp(49/200)*(x-49/200)^10+1/39916800*exp(49/200)*(x-49/200)^11
``````

I´m looking for a method (That include whatever program) not based in language programming, as much batch or somithing like that...

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
• `\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 Nov 23 '10 at 9:11
• @Dennis: freak! :) – akira Nov 23 '10 at 14:37
• @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. Nov 23 '10 at 15:19
• @Dennis: Well, I suppose I can download the strawberry perl... – Peterstone Nov 23 '10 at 17:24
• @Dennis: Do you think I could do it with strawberry perl? – Peterstone Nov 23 '10 at 17:25

Well, I´m trying to execute your code... I make a small program (practicalcase1.pl) with the first paragraph of code you wrote:

``````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"
``````

But I recive some messages on the cmd of windows:

``````Semicolon seems to be missing at practicalcase1.pl line 1
Semicolon seems to be missing at practicalcase1.pl line 2
Semicolon seems to be missing at practicalcase1.pl line 3
Semicolon seems to be missing at practicalcase1.pl line 4
String found where operator expected at practicalcase1.pl line 5, near "echo "\$expression""
(Do you need to predeclare echo?)
String found where operator expected at practicalcase1.pl line 6, near "pe "s/\$fun[^)]*\K\)/)\$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/\$ro\\$&\$rc/g""
(Do you need to predeclare pe?)
Can´t modify constant item in scalar assigment at practicalcase1.pl line 2, near "rc"
syntax error at practicalcase1.pl line 2, near "rc"
Execution of practicalcase1.pl aborted due to compilation errors.
``````

What could I do with the errors of type "semicolon seems to..."? What it´s supossed I have to do with the error "String found where operator ..."? What about "Can´t modify constant item in scalar..."? What about "syntax error at practicalcase1.pl line2..."

Thank you so much!

• The code in my answer is written as a (Unix) shell script rather than a Perl script. To use it in Windows it might be easier to convert it to a Perl script. I will update my answer as soon as possible. – Paused until further notice. Nov 23 '10 at 17:44