2013-03-04 5 views
2

У меня есть ужасное большое выражение, выражающее мощность в терминах оператора ** и его необходимо преобразовать в код, который использует функцию pow. То есть я ищу регулярное выражение для поиска и замены таких терминов, как a*b**N*d, a*pow(b,N), где N - целое число.Заменить a * b ** N на a * pow (b, N)

Здесь a, b и c термины, которые могут содержать xy*-+() и целые числа и a*, *d может не присутствовать.

Я как-то застрял, убегая от всех этих персонажей. Я готов вкладывать некоторую ручную постобработку, поэтому регулярное выражение должно быть надежным, но не обязательно совершенным.

EDIT: Как указал Кент, существует трудность, когда b содержит вложенные скобки. В моем случае нет вложенных скобок. Условия - все формы, приведенные в комментарии ниже.

+0

означает 'а + (я + (x * (mn)) + j) ** p' будет преобразовано в 'a + pow ((i + (x * (mn)) + j), p)'? – Kent

+1

Я чувствую, что это не работа для регулярного выражения ... – Kent

+0

Да. Однако термины скорее выглядят как «4 * y ** 2 * (- 2 * x + 1) * (- y + 1) ** 2'. Что ты предлагаешь? – Jan

ответ

1

Похоже, эта проблема не может быть решена в общем, регулярных выражений, потому что вам нужно, чтобы сбалансировать скобки как-то - - и это задача для синтаксического анализатора.

Что-то вроде этого выполнит работу, где нет парнеров: %s/\(x\|y\|\d\+\)\*\*\(\d\+\)/pow(\1,\2)/gc.

И что-то вроде этого, если может быть только одна пара скобок вокруг термина: %s/\(([xy0-9+-\* ]\+)\|x\|y\|\d\+\)\*\*\(\d\+\)/pow(\1,\2)/gc

BTW это напоминает мне о this вопрос НЕМНОГО =)

+0

+1 для указания этого. – Jan

+0

Спасибо, это работает безупречно! – Jan

1

Если я вас правильно понимаю, вы можете попробовать использовать регулярные выражения группировки, чтобы выделить категории для извлечения:

Так что это регулярное выражение:

(a\*)(b)\*{2}(N)\*d

Вы можете извлечь группы следующим образом:

\1pow(\2,\3) 

опорные группы:

\1 = (a\*) 
\2 = (b) 
\3 = (N) 
+0

Спасибо, я попробую это .. – Jan

1

Вы можете попробовать это

Regex: (\([0-9xy*-]+\)|[0-9xy]+)\*\*([0-9]+)

Заменить: pow($1,$2) или pow(\1,\2)

+0

Спасибо, позвольте мне проверить ... – Jan

+0

K, это работает ! Я только должен был опустить плюсы и избежать(). Но это может быть связано с магией vim. – Jan

+1

это не будет работать для вложенных скобок. например в моем комментарии. @Jan вы должны четко определить, какой случай в вашем реальном файле, а что нет. btw, vim имеет «очень волшебный», который может сэкономить некоторые побеги. – Kent

Смежные вопросы