CSVTool

文章目录
  1. 1. CSV解析器

CSV解析器

class_name CSVTool extends Object

# 使用 static 构造静态函数,可无需加载脚本,直接以 类名.函数名(CSVTool.load) 的方式调用方法
static func load(csv_path: String):
	assert(FileAccess.file_exists(csv_path), "文件不存在!")  # 使用 assert 进行断言,如果传回条件为false会直接打断后续操作。file_exists 方法如果获取不到文件,返回false。
	var file: FileAccess = FileAccess.open(csv_path, FileAccess.READ)  # 打开 CSV 文件进行读取操作
	var head: PackedStringArray = file.get_csv_line(",")  # 读取第一行作为表头(标题行)
	var type: PackedStringArray = file.get_csv_line(",")  # 读取第二行作为数据类型定义行
	file.get_csv_line(",")  # 此代码仅用于跳过注释行
	var items = []  # 用于存储所有的数据

	while not file.eof_reached():  # 循环读取整个文件,如果光标已经读到了文件末尾,eof_reached 会返回 true。
		var data: PackedStringArray = file.get_csv_line(",")  # 从第三行开始,for 循环读取当前行数据。
		var row: Dictionary = {}  # 存储当前行数据

		for i in data.size():  # 遍历表头的每一个列标题
			var title = head[i]  # 获取列标题,作为字典的键名。
			var value = data[i]  # 获取单元格,作为字典的键值。

			match type[i]:  # match 作用相当于 type[i] == int/flo……。即,寻找第i个元素,并确认其是否为对应类型代码。行(第i个)列(是否为对应类型列)都确定就可以找到值了。
				"int": row[title] = value.to_int()
				"flo": row[title] = value.to_float()
				"boo": row[title] = bool(value.to_int())
				"tex":
					row[title] = (ResourceLoader.load(value) as Texture) if ResourceLoader.exists(value) else null
				"ori":
					var ori = []
					# 目前功能只具备初步效果,分析格式字符串中是否有player关键字,存在则获取对应属性
					for item in value.strip_edges().split("|"):
						ori.append(Player.get(item) if item.begins_with("player") else item)
					# 查找 title 为 "dialog" 的字段并进行 % ori 操作
					for key in row.keys(): if key == "dialog": row[key] = row[key] % ori
				"arr":
					var elements = []
					for element in value.strip_edges().split("|"):
						var temporary = []
						# 数据类型转化
						for item in element.split(","):
							temporary.append(item.to_float() if item.is_valid_float() else item.to_int() if item.is_valid_int() else item)
						if title == "checks": temporary.resize(3)  # 标题为 checks 表示这是一个用于检定选项的数组,使用 resize 方法调整数组元素个数,避免调用时因数量不足而报错
						elements.append(temporary)
					row[title] = elements
				
				_: row[title] = value
		
		if not row.is_empty(): items.append(row)  # 将所有数据添加到 items 数组中, 方法 is_empty 会为空字典返回true。

	#for row in items:
		#for title in row.keys():
			#if type[head.find(title)] == "plo":
				#for placeholder_list in oris:
					#for i in range(placeholder_list.size()):
						#if placeholder_list[i].begins_with("player"): placeholder_list[i] = Player.get(placeholder_list[i])
				## 替换占位符
				#row[title] = row[title].format(Array(oris[items.find(row)]))

	file.close()  # 读取完成后关闭文件
	return items
本文作者:晝行燈

版权声明:本文采用 CC BY-NC 4.0 协议授权

转载需注明作者及原文链接: https://mansifield.pages.dev/a7f4cx/