为什么这个正则表达式替换替换原始正则表达式?

时间:2015-09-24 05:30:45

标签: python regex

我正在尝试使用re.sub来替换此文件中B2Ab的所有不同组合,例如B2Az。查找部分工作正常,但每次进行替换时,它都会替换原始正则表达式。我显然遗漏了一些非常简单但却无法找到它的东西。

这是我正在解析的文件的片段:

                    <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="GENB2AbE" t:S="1" t:SC="5">
                                                    <t:ION t:SA="RegisterObj" t:H="3978" t:P="2058" t:N="RE11 Data Log" t:CI="Log_Register" t:L="GENB2Ab">
                                                                            <t:ION t:SA="ModuleObj" t:H="2059" t:P="132" t:N="Data Rec 12" t:CI="DataRecorder_Module" t:L="B2Ab2SBrkr" t:S="1" t:SC="5">
                        <t:IH>
                            <t:CH t:H="43715">
                            </t:CH>
    <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="PMDC_B2_A_b_E" t:S="1" t:SC="5">
    <t:IH>
                            <t:CH t:H="43715">
                            </t:CH>
    <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="PMDC-B2-A-b_E" t:S="1" t:SC="5">

这是我多次尝试使用此功能的最新版本:

var1 = 'B'
var2 = '2'
var3 = 'A'
var4 = 'b' 
var5 = 'z'                  
fname = 'example.txt'        
regexfind(fname,var1,var2,var3,var4,var5)

def regexfind(filename,varl1,varl2,varl3,varl4,varlr,):

    pattern = re.compile('([_-]?['+varl1+'][_-]?['+varl2+'][_-]?['+varl3+'][_-]?['+varl4+'][_-]?)')
    repl = re.compile('([_-]?['+varl1+'][_-]?['+varl2+'][_-]?['+varl3+'][_-]?['+varlr+'][_-]?)')

    f = open(filename,'rb')
    searchstrs = f.readlines()
    i=0
    for line in searchstrs:
        for match in re.finditer(pattern, line):
                    print 'Found on line %s: %s' % (i+1, match.groups())
                    #Showing decompiled patterns for ease of explanation
                    line = re.sub(r'[_-]?['+varl1+'][_-]?['+varl2+'][_-]?['+varl3+'][_-]?['+varl4+'][_-]?',\
                                  r'[_-]?['+varl1+'][_-]?['+varl2+'][_-]?['+varl3+'][_-]?['+varlr+'][_-]?', line.rstrip())
                    print(line)

这是我从以上代码输出的内容:

 Found on line 1: ('B2Ab',)
 <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="GEN[_-]?[B][_-]?[2][_-]?[A][_-]?[z][_-]?E" t:S="1" t:SC="5">
 Found on line 1: ('B2Ab',)
 <t:ION t:SA="RegisterObj" t:H="3978" t:P="2058" t:N="RE11 Data Log" t:CI="Log_Register" t:L="GEN[_-]?[B][_-]?[2][_-]?[A][_-]?[z][_-]?">
 Found on line 1: ('B2Ab',)
 <t:ION t:SA="ModuleObj" t:H="2059" t:P="132" t:N="Data Rec 12" t:CI="DataRecorder_Module" t:L="[_-]?[B][_-]?[2][_-]?[A][_-]?[z][_-]?2SBrkr" t:S="1" t:SC="5">
 Found on line 1: ('_B2_A_b_',)
 <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="PMDC[_-]?[B][_-]?[2][_-]?[A][_-]?[z][_-]?E" t:S="1" t:SC="5">
 Found on line 1: ('-B2-A-b_',)
 <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="PMDC[_-]?[B][_-]?[2][_-]?[A][_-]?[z][_-]?E" t:S="1" t:SC="5">

我应该得到这个:

 Found on line 1: ('B2Ab',)
 <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="GENB2AzE" t:S="1" t:SC="5">
 Found on line 1: ('B2Ab',)
 <t:ION t:SA="RegisterObj" t:H="3978" t:P="2058" t:N="RE11 Data Log" t:CI="Log_Register" t:L="GENB2Az">
 Found on line 1: ('B2Ab',)
 <t:ION t:SA="ModuleObj" t:H="2059" t:P="132" t:N="Data Rec 12" t:CI="DataRecorder_Module" t:L="B2Az2SBrkr" t:S="1" t:SC="5">
 Found on line 1: ('_B2_A_b_',)
 <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="PMDC_B2_A_z_E" t:S="1" t:SC="5">
 Found on line 1: ('-B2-A-b_',)
 <t:ION t:SA="ModuleObj" t:H="2058" t:P="132" t:N="Data Rec 11" t:CI="DataRecorder_Module" t:L="PMDC_B2_A_z_E" t:S="1" t:SC="5">

提前感谢您对我在这里缺少的任何建议。

2 个答案:

答案 0 :(得分:2)

替换不是一种模式。它唯一的特点是它用捕获组内容替换序列\1\2等。因此,您无法在替换部件中匹配下划线和短划线;你想从模式中复制它们。

pattern = re.compile('([_-]?'+varl1+'[_-]?'+varl2+'[_-]?'+varl3+'[_-]?)'+varl4+'([_-]?)')
re.sub(pattern, r'\1' + varlr + r'\2', line.rstrip())

例如"PMDC_B2_A_b_E",这会将"_B2_A_"_"分别捕获到\1\2,然后在替换中将其恢复,并将z夹在中间在最终_B2_A_z_替换之间,制作最终字符串"PMDC_B2_A_z_E"

答案 1 :(得分:0)

您需要定义自己的替换功能。

def repl(matchobj):
     return varl1+varl2+varl3+valr4

line = re.sub(r'[_-]?['+varl1+'][_-]?['+varl2+'][_-]?['+varl3+'][_-]?['+varl4+'][_-]?',repl, line.rstrip())

这种东西。在功能中,你可以返回任何你想要的东西。