匹配python中的特定字符串+任何浮点数

时间:2010-11-06 16:21:52

标签: python 3d

我正在为Luxology modo(3D和VFX应用程序)编写一个脚本,它使用python作为脚本语言。在我的脚本的某处,我正在阅读从其他应用程序输出的文本文件,并从该文本文件的行创建材料和图像映射。我正在做的事情之一是从这个文本文件创建一个通道名称字典,并将每个通道名称映射到modo的内部通道名称,因此modo可以理解如何处理这个通道。这是一个代码片段:

# this is a dictionary of the channel names in the textures.txt file
# mapped to modo's internal channel names
channels = {'color':'diffColor', 'specular':'specAmount', 'normalmap':'normal'}
for channel in channels:
    if channel in materials[mat].keys():
============AND SO ON==============

一切都按预期工作,但还有一个渠道 - 位移。问题是它不仅仅是一个字符串作为其他通道,而是一个字符串后跟一个浮点数,这是一个位移的比例因子,如下所示: 位移19.378531

现在我想在modo中创建位移图像映射,因为我已经在使用其他地图(颜色,法线,高光),而不以任何方式使用这个“比例因子”数字。这似乎很容易,我试图使用正则表达式匹配字符串“位移”后跟随机浮点数,但它不起作用(或者,我没有正确使用它)!

我如何告诉python而不是

channels = {'color':'diffColor', 'specular':'specAmount', 'normalmap':'normal', 'displacement':'displace'}

这样做:

channels = {'color':'diffColor', 'specular':'specAmount', 'normalmap':'normal', 'displacement' + 'ANY_FLOAT_NUMBER':'displace'}

3 个答案:

答案 0 :(得分:1)

你可以使用标准字符串方法从字符串中剥离系数,如果它以'displacement'开头:

for material in materials[mat].keys():
    if material.startswith('displacement'):
        # coefficient = float(material.split('displacement')[1])
        material = material.rstrip('0123456789.')
    if material in channels:
        channelName = channels[material]
        ...

我添加了注释掉的指令,如果你以后决定要系数,你可以取消注释(如果你开始获得位移假象,可能会很重要!)。


阅读评论和完整代码后进行编辑。

您不能在字典键中包含任何编程或变化的内容。但是如果你想保留你已经拥有的模式,最简单的解决方案就是忽略我上面的建议,只需在开始使用这样的快速循环搜索之前删除最后的浮点数:

for channel in channels:
    for key in materials[mat].keys():
        if "." in key:
            materials[mat][key.rstrip("0123456789.")] = materials[mat].pop(key)
    if channel in materials[mat].keys():

答案 1 :(得分:0)

我不完全确定我理解这个问题,但我认为你只需做一些效率低下的事情:

for material in materials:
    if material in channels:
        ...
    if 'displacement' in material:
        ...

答案 2 :(得分:0)

根据您的pastebin,我认为这应该适合您:

# ...
infile.close()

channels = {'color':'diffColor', 'specular':'specAmount', 'normalmap':'normal'}
re_dis = re.compile(r'displacement\s[-+]?[0-9]*\.?[0-9]+')

for material, values in materials.items():
    lx.eval('select.item {Matr: %s} set textureLayer' % material)
    uvmap = materials[material]['uvmap']
    for v in values:
        m = re_dis.match(v)
        if m or v in channels.keys():
            lx.eval('shader.create constant')
            lx.eval('item.setType imageMap textureLayer')
            imagepath = materials[material][v]
            imagename = os.path.splitext(os.path.basename(imagepath))[0]
            lx.eval('clip.addStill {%s}' % imagepath)
            lx.eval('texture.setIMap {%s}' % imagename)
            if m:
                # we can't auto map to the channels dict
                lx.eval('shader.setEffect %s' % 'displace')
            else:
                lx.eval('shader.setEffect %s' % channels[v])

另外,不要忘记将import re添加到脚本的顶部。