1

以下のようなファイルがあります。これは、ルール定義 (つまり rd-6) の参照を含む構成の一部です。構成ファイルの構造は、ルールベースとルール定義の名前を除いて、常に同じように見えます。この部分はルールベース定義です(この質問の目的のために、これは私のRB-definitions.txtでもあります)

##Rulebase-definition  
rulebase bb
      action priority 6 dynamic-only ruledef rd-6 charging-action throttle monitoring-key 1
      action priority 7 dynamic-only ruledef rd-7 charging-action p2p_Drop
      action priority 139 dynamic-only ruledef rd-8 charging-action p2p_Drop monitoring-key 1
#exit

ここに ruledef-definition の例があります (これは、この上昇中のこの質問で私が探している出力でもあります)

##Ruledef-definition
ruledef rd-8
          ip server-ip-address range host-pool BB10_RIM_1
          ip server-ip-address range host-pool BB10_RIM_2
#exit
ruledef rd-3
          ip any-match = TRUE
#exit

上記のように、raw_input() によって指定された特定のルールベース名 (ルールベース定義を含む) を一致させ、ファイル RB-definitions.txt に保存することができました。また、RB-definitions.txt のルール定義名 (名前のみ) を照合し、以下のように ruledef_list に格納することができました。

RDFile = open('RB-definitions.txt')
txt2 = RDFile.read()
ruledef_list = []
for match2 in re.findall((?<=ruledef)((?:.|\n)*?)(?=charging-action), txt2):
    print match2 +"\n" 
    ruledef_list.append(match2)

しかし、上記のように、ruledef-defitnition から特定の ruledef を一致させる必要がある場合、失敗し続けます。ruledef ワードは常に行の最初にある

start_tag =    '^ruledef ' #additional space char
content = '((?:.|\n)*?)'                                
end_tag = '#exit'

for RD_name in ruledef_list:
 print RD_name
 for match in re.findall(start_tag + RD_name + content + end_tag, txt):
    print match + end_tag + "\n" 

「^ruledef」、「^ruledef\s+」、さらには「([ruledef ])\b」を試してみましたが、どれも機能しません。最初の単語を計算する必要があります。そうでない場合、「ruledef」から始まるルールベース定義の一部にも一致するからです。

行内の定義された最初の単語から次の「#exit」までのすべてを一致させるにはどうすればよいですか? 出力として、私は以下を得ることができました

ruledef rd-8
      ip server-ip-address range host-pool BB10_RIM_1
      ip server-ip-address range host-pool BB10_RIM_2
#exit
ruledef rd-3
      ip any-match = TRUE
#exit

理解を深めるために、ここで設定例を含むスクリプト全体を見つけてくださいhttp://pastebin.com/q3VUeAdh

4

1 に答える 1

2

複数行モードがありません。それ以外の場合^は、文字列全体の先頭でのみ一致します。また、(?:.|\n)singleline/dotall モード (任意の 文字に.一致させる) を使用することで、これを回避できます。

start_tag = r'^ruledef ' #additional space char
content = r'(.*?)'                                
end_tag = r'#exit'

...

for match in re.findall(start_tag + RD_name + content + end_tag, txt, re.M|re.S):
    ...

これにより、の内容が得られることに注意してくださいruledef(つまり、そのcontent部分に一致したものだけ - no ruledef、no name、no #exit). If this is not what you want, simply remove the parentheses incontent`:

...
content = r'.*?'
...

ところで、貪欲でない量指定子の代わりに否定的な先読みを使用する方が効率的かもしれません (ただし、そうする必要はありません。速度が重要な関心事である場合は、これをプロファイリングしてください)。

...
content = r'(?:(?!#exit).)*'
...

最後に、すべての正規表現パターンに生の文字列を使用する方法に注意してください。これは Python での良い習慣です。そうしないと、複雑なエスケープ パターンで問題が発生する可能性があります (つまり、一部をダブル エスケープする必要があります)。

于 2013-06-30T16:04:02.183 に答える