2012-12-13 7 views
7

は、乗算記号「*」「テンソル」とし、「p_tensor」を使用して、以下の置換規則と電源記号「^」に置き換えたい:AWKまたはsedまたはPerlでそのような置換を行う方法は?

a(k)^n --> p_tensor(n,a(k)) 
    a(i)*a(j) --> tensor(a(i),a(j)), when i=/=j 

しかしを記号「*」は番号の間にあるときと、 3 * a(i)のようなa(i)の場合、シンボル「*」はそのまま保持する必要があります。

ので、たとえば、

5*a(i)*a(j)*(a(k1)+3*a(k2)) --> 5*tensor(tensor(a(i),a(j)),a(k1)+3*a(k2)) 
    a(i)^2*a(j)^2 --> tensor(p_tensor(2,a(i)),p_tensor(2,a(j))) 
    ... 

は今、私はAWKやsedのか、Perlを使用して、以下の式を再フォーマットする:

3*a(3)^2+6*a(1)^2*(5*a(2)^2-2*a(4))+6*a(2)*a(4)+6*a(1)*(-4*a(2)*a(3)+a(5)) 

任意のアイデアはどのように?置換後の

期待される結果は

3*p_tensor(2,a(3))+6*tensor(p_tensor(2,a(1)),(5*p_tensor(2,a(2))-2*a(4))+6*tensor(a(2),a(4))+6*tensor(a(1),(-4*tensor(a(2),a(3))+a(5)) 
+0

なぜ '*'の一部を 'tensor'で置き換えるのですか?つまり、最初の '3 * a(3)^ 2'は' 'テンソル(3、p_tensor(2、a(3))' 'のように見えます。 – ceyko

+0

2つのa(i)の間のバイナリ演算子であるシンボル "*"を置き換えてください。 –

+0

私は単純な方法、特にその特殊なケースを考えることはできません...少なくともクリーンな方法ではありません。元の式を構文木に構文解析し、必要に応じて演算を使用するように変換します。 – ceyko

答えて

7

正規表現は、任意のネストを行うことはできませんする必要があり、またその後、優先順位と結合を行うことができます。そのためにはパーサーが必要です。しかし、あなたはこれで開始することにより十分に近い得ることができます:

たPerl:

while(<>) { 
    s/(a\(\d+\))\^(\d+)/p_tensor($2,$1)/g; 
    s/(a\((\d+)\))\*(a\((\d+)\))/tensor($1, $3)/g if $2 != $4; 
    print; 
} 

近く、あなたに単一のレベルを取得します。余分なネストは、必要な最大ネスト深度になる再帰的に定義されたパターンを追加することで "偽装"することができます(多くの場合、実際には3〜4レベルの深さはめったにありません。

echo "3*a(3)^2+6*a(1)^2*(5*a(2)^2-2*a(4))+6*a(2)*a(4)+6*a(1)*(-4*a(2)*a(3)+a(5))" | perl t.pl 

または類似した何か:

はでそれを試してみてください。

+0

ありがとう、ありがとう、トニー –

+0

@OsirisXu –

+0

"6 * a(1)^ 2 *(5 * a(2)^ 2-2 * a(4))"から "6 *テンソル(p_tensor(2、a 1))、(5 * p_tensor(2、a(2)) - 2 * a(4))となる。現在のスクリプトでは、 "6 * p_tensor(2、a(1))*(5 * p_tensor(2、a(2)) - 2 * a(4))"に変換されます。 –

関連する問題