【问题标题】:Search Patterns replacement using lambda使用 lambda 替换搜索模式
【发布时间】:2013-02-20 13:54:30
【问题描述】:

我需要使用搜索替换模式之前和之后写入文件。我写了下面的代码。我在写入输出文件时使用了函数,它工作得很好。但是我有大约 20 种这样的替换模式,我觉得我写的代码不好,因为我需要为所有这些替换创建函数。能否请您告诉我有没有其他方法可以实现这一点?

import re

Report_file = open("report.txt", "w")
st = '''<TimeLog>
<InTime='10Azx'>1056789</InTime>
<OutTime='14crg'>1056867</OutTime>
<PsTime='32lxn'>1056935</PsTime>
<ClrTime='09zvf'>1057689</ClrTime>
</TimeLog>'''

def tcnv(str):
     Report_file.write("Previous TS:  " + str + "\n\n")
     v1 = re.search(r"(?i)<clrtime='(\d+\w+)'>", str)
     val1 = v1.group(1)

     v2 = re.search(r"(?i)(<clrtime='(\d+\w+)'>(.*?)</clrtime>)", str)
     val2 = v2.group(3)

     soutval = "<Clzone><clnvl='" + val1 + "'>" + val2 + "</clnvl></Clzone>" 
     Report_file.write("New TS:  " + soutval + "\n")
     return soutval


st = re.sub(r"(?i)(<clrtime='(\d+\w+)'>(.*?)</clrtime>)", lambda m: tcnv(m.group(1)), st)
st = re.sub(r"(?i)<intime='(\d+\w+)'>(.*?)</intime>", "<Izone><Invl='\\1'>\\2</Invl></Izone>", st)
st = re.sub(r"(?i)<outtime='(\d+\w+)'>(.*?)</outtime>", "<Ozone><onvl='\\1'>\\2</onnvl></Ozone>", st)
st = re.sub(r"(?i)<pstime='(\d+\w+)'>(.*?)</pstime>", "<Pszone><psnvl='\\1'>\\2</psnvl

【问题讨论】:

    标签: python regex python-3.x


    【解决方案1】:

    我不明白你为什么把 re.IGNORECASE 标志放在(?i) 的形式下,所以我没有使用它下面的解决方案,并且模式根据你的示例在必要的地方用大写字母编写

    请注意,您应该使用with 语句打开文件,这样会好得多:

    with open('filename.txt','rb') as f:
    
        ch = f.read() 
    

    答案

     import re
    
     st = '''<InTime='10Azx'>1056789</InTime>
     <OutTime='14crg'>1056867</OutTime>
     <PsTime='32lxn'>1056935</PsTime>
     <ClrTime='09zvf'>1057689</ClrTime>
     '''
    
     d = dict(zip(('InTime','OutTime','PsTime','ClrTime'),
    
                  (('Izone><Invl','/Invl></Izone'),
                   ('Ozone><onvl','/onnvl></Ozone'),
                   ('Pszone><psnvl','/psnvl></Pszone'),
                   ('Clzone><clnvl','/clnvl></Clzone'))
                  )
              )
    
     def ripl(ma,d=d):
          return "<{}='{}'>{}<{}>".format(d[ma.group(1)][0],
                                          ma.group(2),
                                          ma.group(3),
                                          d[ma.group(1)][1])
    
     st2 = re.sub(r"<(InTime|OutTime|PsTime|ClrTime)='(\d+\w+)'>(.*?)</\1>",
                 ripl, st)
    
     print '%s\n\n%s\n' % (st,st2)
    

    【讨论】:

    • 感谢您的反馈。因为我是 python 新手,所以我以这种方式打开文件。你能解释一下 ripl 函数吗?
    • 我无法创建包含搜索替换模式前后的报告。
    • @new2python ripl() 是一个函数,用于接收参数 ma 上的 MatchObjects。它使用字典d。我将此字典作为参数d 的默认值。事实上,函数可以由def ripl(ma,dico): 定义,参数dico 将替换函数块中的ddico[ma.group(1)][0]dico[ma.group(1)][1]。为参数定义默认值很有趣,因为函数定义的执行只执行一次(根据定义,您必须了解:描述函数的文本块)
    • @new2python ripl 返回的内容必须是一个字符串:这个字符串用于替换处理文本中的每个匹配项(= 匹配部分)。由于ripl 是一个函数,它返回的内容可能因匹配而异。被替换的匹配(=匹配部分)包含在传递给参数ma的匹配(= MatchObject)中:它是ma.group(0)。我的意思是,正则表达式模式中可能定义了多个组,但是对于每个匹配项,替换的文本部分是完整匹配(即使模式中没有定义组,也会在group(0) 中捕获)跨度>
    • @new2python 我的回答只公开了一次进行多次替换的方式,而不是关于打开、读取和写入文件的方式。一旦你有了替换的文本,你就可以用它做你想做的事了。
    猜你喜欢
    • 2011-08-16
    • 2015-10-09
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    相关资源
    最近更新 更多