4

FORTRAN コードでパフォーマンスを向上させるために、4 番目のインデックスが 2 番目に移動するように配列のインデックスを並べ替えたいのですが、たとえば、次の行を変更したいと考えています。

ts(l,i,j,k) = ts(l,i,j,k1(i,j))

ts(l,k,i,j) = ts(l,k1(i,j),i,j)

これは行の例にすぎないことに注意してください。インデックスは常に i、j、k、l と呼ばれるわけではありません... 私は配列の名前とランクを知っているだけです。したがって、4 つの引数をカンマで区切ることはできません。これは、1 つの引数がカンマを含む行列になることもあるためです (上記の場合は k1(i,j))。だから私の最初のアイデア

sed -r  's/ts\(([^,]+),([^,]+),([^)]+),([^,]+)\)/ts\(\1,\4,\2,\3\)/g' *.F

この場合 (上記のコード行の右側)、次のように失敗します。

ts(l,k,i,j) = ts(l,j),i,j,k1(i)

私が必要としているのは、最大 1 つのブラケットが開かれている場合にのみ、配列のインデックスを分割する正規表現です。誰かがsed/python/perlでこれを行う方法のヒントを教えてもらえますか?

幸運をお祈りしています

4

2 に答える 2

2

直接正規表現は少し難しいかもしれません。スクリプト言語が利用できる場合は、次のことを試してください。配列アクセスを含む行を検出した後。(パイソンで)

import re
def getArguments(rhs):
    """
        Separates string on commas that are in the first level parentheses
    """
    lvl = 0
    argSplits = []
    for i, c in enumerate(rhs):
        if c == '(':
            lvl += 1
            if lvl == 1:
                argSplits.append(i)
        elif c == ')':
            lvl -= 1
            if lvl == 0:
                argSplits.append(i)
                break
        if lvl < 0:
            raise ValueError('Parentheses do not match')
        if lvl == 1:
            if c == ',':
                argSplits.append(i)
    args = []
    for i in range(len(argSplits)-1):
        args.append(rhs[argSplits[i]+1:argSplits[i+1]])
    return args

line = r'ts(l,i,j,k) = ts(l,i,j,k1(i,j))'
# get righthand side of equ
rhs = re.split('=', line)[1]   
# get arguments
args = getArguments(rhs)
# args = ['l', 'i', 'j', 'k1(i,j)']

# try: line = r'ts(l,i,j,k) = ts(l,i,j,k1(i(am(crazy(!))i),j))'
# you get: getArguments(rhs) --> ['l', 'i', 'j', 'k1(i(am(crazy(!))i),j)'

引数リストを取得したら、文字列を元に戻すときにそれらを並べ替えることができます

于 2013-03-12T14:53:47.933 に答える
2

これは、括弧が例よりも深くネストされていない場合に機能するはずです。

sed -r  's/ts\(((\([^()]*\)|[^(),])*),((\([^()]*\)|[^(),])*),((\([^()]*\)|[^(),])*),((\([^()]*\)|[^(),])*)\)/ts(\1,\7,\3,\5)/g' *.F

とてもきれいというわけではありません...

説明:

(        # Match and capture...
 (       # either
  \(     #  an opening parenthesis
  [^()]* #  any number of non-parenthesis characters
  \)     #  a closing parenthesis
 |       # or  
  [^(),] #  a character besides parentheses or comma
 )*      # any number of times
)        # End of capturing group
于 2013-03-12T13:07:23.543 に答える