Perl: манипуляции со строками, окружающие математическое выражение
Я изучаю Perl, я хотел бы окружить такое выражение
function1(mathematical_expresion1)*function2(mathematical_expresion2)
Где 'function1' и 'function2' могут быть любым словом и объединять числа внутри, например, function1 может быть fun3dec, fun4nels, factor9 или чем-то еще... так что мой код станет таким
surrounded(function1(mathematical_expresion1)*function2(mathematical_expresion2))surroundedend
Где окружены и окружают - цепочки струн.
Так что, если у меня есть такое выражение:
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+1/479001600*exp(-49/200)*(x-49/200)^12
Я мог бы окружить все умножение двух терминов в предыдущем выражении.
Спасибо, что научили меня Perl!
1 ответ
Вот первое (неполное) решение, которое поднимает некоторые вопросы о том, что вы хотите сделать:
Для краткости и ясности я использовал более простой синтаксис - аргументы функций - это простые цифры или выражения. Имена функций состоят из отдельных букв. Объемный звук заменен на S{}
, От этого легко перейти к вашему примеру.
sample.txt:
1 A(1)
2 A(1)*B(2)
3 C(2)+A(1)*B(2)
4 C(A(1)*B(2))
5 C(A(1)*B(3)+C(4))
6 A(1)*B(2)+C(3)*D(4)
7 A(1)*B(2)*C(3)*D(4)
8 A(B(2)*C(3))*D(4)
9 C(A(1)+B(3))*C(4)
perl < sample.txt -pe 's/(\w\(\d+\)\*\w\(\d+\))/S{\1}/g'
1 A(1)
2 S{A(1)*B(2)}
3 C(2)+S{A(1)*B(2)}
4 C(S{A(1)*B(2)})
5 C(S{A(1)*B(3)}+C(4))
6 S{A(1)*B(2)}+S{C(3)*D(4)}
7 S{A(1)*B(2)}*S{C(3)*D(4)}
8 A(S{B(2)*C(3)})*D(4)
9 C(A(1)+B(3))*C(4)
Итак, что должна делать строка 7? Что должна делать строка 8?
Строка 9 не работает, потому что мой код недостаточно умен, и я не знаю, НУЖЕН ли он, чтобы он работал.
Я полагаю, что вам действительно нужен парсер (например, yacc), а также лексер. В Perl есть лексер, но нет парсера.
Проблема здесь в том, что вы ищете экземпляры:
<expression> `*` <expression>
но так как выражение определяется как
<expression> = \d+
| <function>
| <expression> <op> <expression>
Вам нужен автомат, чтобы сделать это правильно. Регулярные выражения Perl просто не могут этого сделать.
ПРИМЕЧАНИЕ: прошло уже десять лет с моего курса по компиляции, поэтому я могу немного колебаться в своей терминологии.