我已经看过How do I re.search or re.match on a whole file without reading it all into memory?和TypeError: sequence item 1: expected a bytes-like object, str found,但这两个问题的解决方案对我来说并不奏效
因此,本文的目标是在文本文件中对模式进行正则表达式搜索,特别是从示例文本文件
ParameterValue = Texture2D'/Game/Characters/Slashers/Bear/Textures/Outfit01/T_BEHead01_BC.T_BEHead01_BC' ParameterValue = Texture2D'/Game/Characters/Slashers/Bear/Textures/Outfit01/T_BEHead01_BC.T_BEHead01_BC'
我想提取“/Game/Characters/Slashers/Bear/Textures/ought01/T_behahead01_BC”和“/Game/Characters/Slashers/Bear/Textures/ought01/T_behahead01_BC”,我知道这是字符串正则表达式模式:
Texture2D\'(.*)\.
和捕获组的一部分。组(1)
相关代码部分为:
with open(mytool.propstxt_path, 'r+') as f:
data = mmap.mmap(f.fileno(), 0)
match_obj = re.match('Texture2D\'(.*)\'', data)
print(match_obj.group(1))
我使用mmap将整个文本文件读取到内存中,这样数据就像一个普通字符串一样,可以进行正则表达式匹配
但是,我遇到了一个问题:无法在这一行的类似字节的对象上使用类似字符串的模式:match_obj=re.match('Texture2D'(.*)',data)
因此,我尝试使用regex和compile将字符串模式转换为类似字节的模式。但不幸的是,这导致match_obj为nothing,因为打印它时返回None,所以我认为下面的代码段不正确
with open(mytool.propstxt_path, 'r+') as f:
data = mmap.mmap(f.fileno(), 0)
regex = rb'Texture2D\'(.*)\''
pattern = re.compile(regex)
match_obj = re.match(pattern, data)#'Texture2D\'(.*)\''
print(match_obj)
我还尝试在模式之前放置一个b以将其转换为字节,但这再次导致match_obj为None,没有属性。group()
with open(mytool.propstxt_path, 'r+') as f:
data = mmap.mmap(f.fileno(), 0)
match_obj = re.match(b'Texture2D\'(.*)\'', data)
print(match_obj.group(1))
我尝试的最后一件事是使用.decode()将数据解码到UTF-8。执行以下操作,但返回错误mmap.mmap对象没有属性decode
with open(mytool.propstxt_path, 'r+') as f:
data = mmap.mmap(f.fileno(), 0).decode('UTF-8')
match_obj = re.match('Texture2D\'(.*)\'', data)
print(match_obj.group(1))
我想尝试的最后一件事就是逐行读取整个文件,因为mmaps意味着您需要使用像regex这样的字节,我不知道在我的情况下该怎么做
我的全部代码如下所示,但警告是针对blender插件、创建面板等
#import all libraries including those needed for regex matching and mapping string to memory
import bpy, re, mmap
class PathProps(bpy.types.PropertyGroup):
propstxt_path: bpy.props.StringProperty(name="Select PropsTxt File ", description="Select a File", subtype="FILE_PATH")
texloc_path: bpy.props.StringProperty(name="Select Exported Game Folder ", description="Select a Folder", subtype="DIR_PATH")
class DBDShaderScript_PT_main_panel(bpy.types.Panel):
bl_label = "DBD Shader Maps"
bl_idname = "DBDShaderScript_PT_main_panel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "DBD Shaders"
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.prop(mytool, "propstxt_path")
layout.prop(mytool, "texloc_path")
layout.operator("dbdshaderscript.addbasic_operator")
class DBDShaderScript_OT_add_basic(bpy.types.Operator):
bl_label = "Add Basic Shader Map (Every Material Except Hair)"
bl_idname = "dbdshaderscript.addbasic_operator"
def execute(self, context):
#make reference to user inputted file name
scene = context.scene
mytool = scene.my_tool
#find the selected material, s_mat stands for selected material
s_mat = bpy.context.active_object.active_material
s_mat.use_nodes = True
#store new link function to variable
link = s_mat.node_tree.links.new
#assign Principled BSDF to a variable so can be referenced later
#so that nodes can link to it
principled_node = s_mat.node_tree.nodes.get('Principled BSDF')
#start adding all nodes and respective links to shader map
srgb_node = s_mat.node_tree.nodes.new("ShaderNodeSeparateRGB")
srgb_node.location = (-200,150) # x,y
link(srgb_node.outputs[2], principled_node.inputs[4])
node = s_mat.node_tree.nodes.new("ShaderNodeValToRGB")
node.location = (-500,50) # x,y
link(node.outputs[0], principled_node.inputs[7])
#node = s_mat.node_tree.nodes.new("ShaderNodeSeparateRGB")
#node.location = (-200,100) # x,y
#link(node.outputs[2], principled_node.inputs[4])
with open(mytool.propstxt_path, 'r+') as f:
data = mmap.mmap(f.fileno(), 0)
match_obj = re.match('Texture2D\'(.*)\'', data)
print(match_obj.group(1))
#add image texture nodes
texImage = s_mat.node_tree.nodes.new('ShaderNodeTexImage')
#example loading image
#texImage.image = bpy.data.images.load("C:\\Users\\myName\\Downloads\\Textures\\Downloaded\\flooring5.jpg")
#uncomment this
#texImage.image = bpy.data.images.load(match_obj.group(1)[0])
#make a link to principle BSDF node
link(texImage.outputs[0], principled_node.inputs[0])
return {"FINISHED"}
#register + unregister all classes with a loop
classes = [PathProps, DBDShaderScript_PT_main_panel, DBDShaderScript_OT_add_basic]
def register():
for cls in classes:
bpy.utils.register_class(cls)
#create pointer to all properties
bpy.types.Scene.my_tool = bpy.props.PointerProperty(type = PathProps)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()
好的,所以我解决了我的问题,不完全使用MMAP,因为它们要求按位正则表达式很烦人,我不喜欢。所以我所做的只是将整个文件读入一个字符串,当然这对较长的文件不起作用,但这对我的目的来说是很好的
这是我的解决方案,我刚换了这个
相关问题 更多 >
编程相关推荐