替换为幻影条件python

时间:2018-03-25 13:30:37

标签: python regex python-3.x replace

我有一个包含很多软件参数的文件,它看起来像是:

CMaterial::m_HurkxPrefactor=6.14
CMaterial::m_HurkxFgamma=368800
CRegion::m_FrontDiff1:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=0
CDiffusion::m_Profile=2
CDiffusion::m_Npeak=1e+020
CDiffusion::m_Depth=1.5e-005
CDiffusion::m_Xpeak=0
CRegion::m_FrontDiff2:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=1
CDiffusion::m_Profile=0
CDiffusion::m_Npeak=9e+016
CDiffusion::m_Depth=0.018
CDiffusion::m_Xpeak=0

(有更多行)

有几个区域,第一个“CDiffusion :: m_Enable”控制第一个区域的属性,第二个区域用于设置第二个区域。

我希望获取此文本文件并替换为我的值。 目前我知道如何使用此代码更改多个参数,但是它很难管理文件中参数的重复:

params = {'CDiffusion::m_Type': 3,
          'CDiffusion::m_Depth' : 0.018
          }

编辑:错过了这部分代码

lab, val = [], []
    for k, v in params.items():
        lab.append(k)
        value.append(v)

s = f.read()
for num, val in enumerate(lab):
            s = re.sub('{0}=(.?)*'.format(val), '{1}={0}'.format(value[num], val), s)

但现在我希望例如将“CDiffusion :: m_Type”更改为3,将第二个“CDiffusion :: m_Type”更改为4.

使用此参数列表并根据最后的显示进行更改。

params = {'CDiffusion::m_Type': 3,
          'CDiffusion::m_Type': 4,
}

任何帮助将不胜感激,提前谢谢!

EDIT2: @JoeIddon解决方案正在发挥作用,但我想进一步推动它:

lines = open('Test4.txt').read().strip().split('\n')

params = {
          'CDiffusion::m_Type':  ['3', 'False' ,'4'],
          'CDiffusion::m_Depth': ['5', '6', '5']
         }

with open('Test4.txt', 'w') as fh:
    for l in lines:
        try:
            k, v = l.split('=')
            if params[k] != 'False':
                nl = k + '=' + params[k].pop(0)
            else:
                nl = l
                params[k].pop(0)
        except (KeyError, IndexError, ValueError):
            nl = l
        fh.write(nl + '\n')
        print(nl)
fh.closed

如果某个值在param中,我想不更改该行,在这种情况下为'false'。它似乎不起作用

1 个答案:

答案 0 :(得分:2)

字典键必须是唯一的,以便最后一个字典无效。你真正想要的是一个字典,其中的值是列表。这将允许您按顺序指定替换应该是什么。此外,由于它们是文件中的替换,因此它们必须是字符串,而不是整数。

所以,例如:

params = {
          'CDiffusion::m_Type':  ['3', '4'],
          'CDiffusion::m_Depth': ['5', '6']
         }

现在,要按顺序执行此替换,我们无法使用.replace,因为这会更改所有实例;相反,我们必须编写自己的方法。

为此,我们可以迭代每一行,在'='上拆分,然后从params检索下一个替换值。为此,我们可以弹出列表中的第一个项目(第一个替换),并在编写新行(nl代码时)使用它。

我们需要考虑的唯一最后一件事是当密钥(因此分割的前半部分)不在我们的params字典中时,以及它在字典中时的情况,但由于某种原因,没有替代品(即清单是空的)。这些可以分别用KeyErrorIndexError来捕获(因此我们需要try...except)。此外,经过测试,我意识到并非所有的行实际上都有'=' s,所以我们还需要捕获ValueError,对于这种情况。

<强>更新

你非常接近尝试添加一个没有改变价值的案例,但是你有两件事是错的。

首先,由于Python列表中允许使用不同的数据类型(字符串,整数,更多列表等),因此使用False代替'False'可能更容易。将使检查更容易。

其次,当您检查此案例是否需要跳过(False)时,您正在检查params[k]。这是错误的,因为params[k]将为我们提供替换列表,而不是 next 替换。对于下一次替换,您需要像我们一样pop(0)

所以,代码(params已经定义并且更新):

lines = open('f.txt').read().strip().split('\n')
with open('f.txt', 'w') as fh:
    for l in lines:
        try:
            k, v = l.split('=')
            r = params[k].pop(0)
            if r:
                nl = k + '=' + r
            else:
                nl = l
        except (KeyError, IndexError, ValueError):
            nl = l
        fh.write(nl + '\n')

好的,我刚试过它并且它有效;之后是文件:

CMaterial::m_HurkxPrefactor=6.14
CMaterial::m_HurkxFgamma=368800
CRegion::m_FrontDiff1:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=3
CDiffusion::m_Profile=2
CDiffusion::m_Npeak=1e+020
CDiffusion::m_Depth=5
CDiffusion::m_Xpeak=0
CRegion::m_FrontDiff2:
In CDiffusion: ver_num=1
CDiffusion::m_Enable=0
CDiffusion::m_Type=4
CDiffusion::m_Profile=0
CDiffusion::m_Npeak=9e+016
CDiffusion::m_Depth=6
CDiffusion::m_Xpeak=0

注意第一个CDiffusion::m_Type现在是3,第二个是4,以及第一个CDiffusion::m_Depth现在是如何5和第二个6