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 名称(但只有名称)并将其存储在 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-definition 的特定 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)使用单行/点全模式(.匹配任何 字符):

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部分匹配的内容 - 没有ruledef,没有名称,没有#exit). If this is not what you want, simply remove the parentheses in内容`:

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

顺便说一句,使用负前瞻而不是不贪婪的量词可能更有效(但它不必 - 如果速度对您来说是一个重要问题,请描述这一点):

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

最后,请注意我如何将原始字符串用于所有正则表达式模式。这只是 Python 中的好习惯——否则你可能会遇到复杂转义模式的问题(即,你必须对某些东西进行双重转义)。

于 2013-06-30T16:04:02.183 回答