Попробуй это:
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"
который должен дать вам:
roundn(exp(roundn(49/200,n)),n)+(x-roundn(49/200,n))
Ваше более длинное выражение должно привести к:
roundn(ехр (roundn (49/200, п)), п)+roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))+roundn (1/2, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 2+roundn (1/6, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 3+roundn (1/24, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 4+roundn (1/120, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 5+roundn (1/720, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 6+roundn (1/5040, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 7+roundn (1/40320, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 8+roundn (1/362880, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 9+roundn (1/3628800, п)* roundn (ехр (roundn (49/200, п)), п)*
(Х-roundn (49/200, п))^ 10+roundn (1/39916800, п)* roundn (ехр (roundn (49/200, п)), п)*
(x-roundn (49/200, n)^ 11
объяснение
/exp\([^)]*\K\)/)$rc/g
- закрыть exp(), добавить округлить закрыть
- для строк, которые начинаются с "exp(" и заканчиваются на ")"
\K
делает "exp(" совпадением нулевой ширины, поэтому заменяется только закрывающая пара
s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g
- цепочки цифр с множеством и делением, окружены округленным открытием и округленным закрытием
- строки цифр, которые не начинаются с «^», но могут содержать «/» или «*»
- должно быть всего два или более символов - возможно, есть лучший способ сделать это
- Карат имеет отрицательный взгляд сзади (нулевой ширины), поэтому он не включен, когда замена сделана
s/exp\([^)]*/$ro\$&/g
- открыть exp(), добавить круглое открытие
- перед выражением "exp(", за которым следует ноль или более символов, которые не являются ")", добавьте круглое открытое
$ro
, $rc
и $fun
являются переменными оболочки
- обертывание скрипта Perl в двойные кавычки позволяет расширить эти переменные
$&
содержит полное совпадение, кроме частей с нулевой шириной
- выходить из него, вероятно, не нужно, но я сделал это на всякий случай - чтобы не перепутать оболочку
Было бы не сложно сделать эту работу, если есть более одной функции. Однако, вероятно, он полностью развалится, если они будут вложенными.
Редактировать:
Вот версия сценария Perl:
$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
}
Запустите это так:
perl script.pl < data.txt