【问题标题】:Replace with an apparition condition python替换为幻影条件python
【发布时间】:2018-03-25 13:30:36
【问题描述】:

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

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,
}

任何帮助将不胜感激,在此先感谢!

编辑2: @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

如果参数中有某个值,我不想更改行,在本例中为“假”。不过好像不行

【问题讨论】:

  • 最后一个字典无效,因为同一个键不能指向多个值,前者只会被覆盖。另外,在您的代码示例中,value 在第二个字符串格式中来自哪里?
  • 是否所有这些不同的参数都需要按照这个特定的顺序编写,还是没有关系?
  • 顺序很重要,第一个幻影,=>第一个区域的参数,第二个幻影=>第二个区域的参数
  • @th0mash 所以你想用 3 替换第一次出现的 m_type,用 4 替换第二次出现的 m_type,对吗?
  • 因为顺序很重要,所以不能简单地搜索出现的地方。我建议遍历输入文件,并检查每一行是否匹配。如果该行匹配,则替换值并从您的参数字典中删除使用的项目。

标签: python regex python-3.x replace


【解决方案1】:

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

所以,例如:

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

现在,要按顺序进行替换,我们不能使用.replace,因为它会改变所有出现的情况;相反,我们必须编写自己的方法。

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

我们需要考虑的最后一件事是当键(即拆分的前半部分)不在我们的 params 字典中以及当它在字典中时的情况,但由于某种原因,存在没有替代品(即列表为空)。这些可以分别用KeyErrorIndexErrors 捕获(所以我们需要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

【讨论】:

  • 非常感谢,以后我会努力的!
  • @th0mash 我现在已经对其进行了测试并且它正在工作,请参阅我的更新
  • 非常感谢您,它的工作原理就像一个魅力,但是您能看看我关于我不想改变的价值的第二次编辑!再次感谢您
  • @th0mash 没问题,我又更新了答案。
猜你喜欢
  • 2023-04-09
  • 2018-07-10
  • 2019-05-15
  • 2015-02-02
  • 1970-01-01
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
相关资源
最近更新 更多