写游戏逻辑时,字符串处理无处不在。显示玩家名字、拼接提示文本、解析配置文件、处理用户输入,都离不开对字符串的各种操作。GDScript 的字符串和 Python 很像,但有一些自己的方法和习惯。这篇笔记把我常用的字符串操作整理出来,覆盖实际开发中会遇到的场景。
一、字符串的创建
字符串用双引号或单引号创建,两者完全等价,看个人习惯。我习惯用双引号,因为和大多数语言一致。
gdscript
var name = "Tom"
var msg = '你好'
var empty = ""
多行字符串
GDScript 用三个双引号 """ 或三个单引号 ''' 创建多行字符串:
gdscript
var description = """
这是第一行
这是第二行
这是第三行
"""
多行字符串会保留换行符。注意开头和结尾的换行也会被包含进去,所以通常会在三引号后直接换行,让内容从下一行开始。
转义字符
字符串里可以使用转义字符表示特殊符号:
| 转义 | 含义 |
|---|---|
\n |
换行 |
\t |
制表符 |
\" |
双引号 |
\' |
单引号 |
\\ |
反斜杠 |
gdscript
var text = "第一行\n第二行"
print(text)
# 输出:
# 第一行
# 第二行
二、字符串拼接
用 + 拼接
最简单直接的方式:
gdscript
var first_name = "Tom"
var last_name = "Smith"
var full_name = first_name + " " + last_name
print(full_name) # Tom Smith
注意:+ 只能拼接字符串,不能直接拼数字。如果要把数字拼进去,必须先用 str() 转换:
gdscript
var score = 100
var text = "分数:" + str(score)
print(text) # 分数:100
用 += 追加
gdscript
var text = "Hello"
text += " World"
text += "!"
print(text) # Hello World!
性能提醒
在循环里频繁用 + 拼接字符串会产生大量临时对象,影响性能。如果需要大量拼接,建议用数组收集,最后用 join() 合并,或者用格式化字符串。
三、字符串格式化
1. 用 % 格式化
这是我最常用的方式,类似 Python 的 % 格式化。用 % 加占位符,后面跟上参数数组。
gdscript
var name = "Tom"
var score = 85
var text = "玩家 %s 得了 %d 分" % [name, score]
print(text) # 玩家 Tom 得了 85 分
占位符类型:
| 占位符 | 含义 |
|---|---|
%s |
字符串(任何类型都会转成字符串) |
%d |
整数 |
%f |
浮点数 |
%x |
十六进制整数 |
%c |
单个字符 |
%f 可以指定小数位数:
gdscript
var pi = 3.1415926
print("%.2f" % pi) # 3.14
多个占位符时,参数用数组按顺序传入。如果只有一个占位符,可以不用数组,直接传值:
gdscript
print("分数:%d" % score)
2. 用 format() 方法
format() 方法用 {} 作为占位符,参数传入数组。
gdscript
var text = "玩家 {0} 得了 {1} 分".format([name, score])
print(text) # 玩家 Tom 得了 85 分
占位符里的数字表示参数数组的下标。也可以使用命名参数:
gdscript
var text = "{player_name} 有 {hp} 点生命值".format({
"player_name": "Tom",
"hp": 100
})
print(text) # Tom 有 100 点生命值
format() 的可读性比 % 更好,尤其是参数多的时候。不过 % 写起来更短,两者都可以用,选一个自己喜欢并保持统一就行。
四、常用字符串方法
GDScript 的 String 类型内置了大量方法,下面是我常用的。
1. length() 获取长度
gdscript
var text = "Hello"
print(text.length()) # 5
注意是方法不是属性,要加括号。中文也按单个字符计算:
gdscript
var text = "你好"
print(text.length()) # 2
2. contains() 判断是否包含
gdscript
var text = "Hello World"
if text.contains("World"):
print("包含 World")
3. starts_with() 和 ends_with()
判断字符串是否以指定前缀开头或后缀结尾。
gdscript
var filename = "player.tscn"
if filename.ends_with(".tscn"):
print("是场景文件")
if filename.starts_with("player"):
print("是玩家相关文件")
4. substr() 截取子串
substr(开始下标, 长度) 返回指定范围的子串。
gdscript
var text = "Hello World"
var sub = text.substr(6, 5) # 从下标 6 开始,取 5 个字符
print(sub) # World
如果省略长度,截取到末尾:
gdscript
var sub = text.substr(6)
print(sub) # World
5. find() 和 rfind() 查找子串
返回第一个匹配的下标,找不到返回 -1。
gdscript
var text = "Hello World"
print(text.find("o")) # 4
print(text.find("World")) # 6
print(text.find("xyz")) # -1
rfind() 从后往前找:
gdscript
print(text.rfind("o")) # 7
6. split() 分割
按指定分隔符把字符串拆成数组。
gdscript
var text = "apple,banana,orange"
var parts = text.split(",")
print(parts) # ["apple", "banana", "orange"]
如果不传参数,按空白字符分割:
gdscript
var text = "Tom Jerry Anna"
var parts = text.split()
print(parts) # ["Tom", "Jerry", "Anna"]
7. replace() 替换
把字符串中所有匹配的部分替换成新内容。
gdscript
var text = "Hello World"
var new_text = text.replace("World", "Godot")
print(new_text) # Hello Godot
8. strip_edges() 去除首尾空白
去除字符串开头和结尾的空格、制表符、换行等。
gdscript
var input = " 玩家输入 "
var cleaned = input.strip_edges()
print(cleaned) # "玩家输入"
如果只想去除一侧,用 lstrip() 或 rstrip()。
9. to_upper() 和 to_lower() 大小写转换
gdscript
var text = "Hello"
print(text.to_upper()) # HELLO
print(text.to_lower()) # hello
10. is_valid_int() 和 is_valid_float()
判断字符串能否转换成数字,在用户输入处理时很有用。
gdscript
var input = "123"
if input.is_valid_int():
var num = int(input)
print("转换成功:", num)
else:
print("不是有效整数")
五、字符串与数字互转
数字转字符串
用 str() 函数,或者用格式化:
gdscript
var num = 100
var text1 = str(num) # "100"
var text2 = "%d" % num # "100"
字符串转数字
用 int() 或 float(),但要注意转换失败会报错。所以先用 is_valid_int() 或 is_valid_float() 判断:
gdscript
var text = "42"
if text.is_valid_int():
var num = int(text)
print(num * 2) # 84
六、字符串比较
字符串可以直接用 ==、!=、<、> 比较。比较规则按字符编码逐位比较。
gdscript
var a = "apple"
var b = "banana"
if a < b:
print("apple 在 banana 前面") # 按字母顺序
注意:字符串比较是区分大小写的,"Apple" 和 "apple" 不相等。需要忽略大小写比较时,先统一转成小写或大写。
gdscript
if a.to_lower() == b.to_lower():
print("忽略大小写相等")
七、遍历字符串中的字符
字符串可以直接用 for 循环遍历,每次得到一个字符:
gdscript
var text = "Godot"
for c in text:
print(c)
# 输出:
# G
# o
# d
# o
# t
如果需要把字符存入数组,可以使用 split("") 但会包含首尾空字符串,需要过滤,或者直接用循环添加到数组。
数组转字符串
join() 方法把字符串数组用指定分隔符连接成字符串:
gdscript
var words = ["Godot", "is", "awesome"]
var sentence = " ".join(words)
print(sentence) # Godot is awesome
var csv = ",".join(words)
print(csv) # Godot,is,awesome
join() 是数组的方法,分隔符写在前面,数组作为调用者。这个写法可能有点反直觉,但用几次就习惯了。
八、字符串与其他类型的拼接
除了 str() 转换后拼接,也可以直接用格式化,这样不用手动转换:
gdscript
var hp = 100
var max_hp = 120
var text = "生命值:%d / %d" % [hp, max_hp]
print(text) # 生命值:100 / 120
或者在 print() 里直接用逗号分隔多个值:
gdscript
print("生命值:", hp, "/", max_hp)
print() 会自动把多个参数转成字符串并用空格连接,调试时特别方便。
九、实战:解析简单的配置行
假设有一个配置文件,每行是 键=值 的格式,我们可以用字符串方法解析:
gdscript
var config_line = "player_speed=200"
var parts = config_line.split("=")
if parts.size() == 2:
var key = parts[0]
var value = parts[1]
if value.is_valid_float():
var speed = float(value)
print("配置:", key, " = ", speed)
else:
print("值不是有效数字")
else:
print("格式错误")
这个例子用到了 split()、is_valid_float()、float(),是实际项目中处理文本配置的典型方式。
十、总结
字符串操作是日常开发中非常高频的技能,GDScript 的 String 类型提供了丰富的方法。重点掌握:
- 拼接:
+、+=,大量拼接时用数组join() - 格式化:
%和format(),选一个坚持用 - 查找:
contains()、find()、rfind() - 截取和分割:
substr()、split() - 修改:
replace()、strip_edges()、to_upper()、to_lower() - 转换:
str()、int()、float(),配合is_valid_int()等判断
建议把这些方法自己跑一遍,尤其是 split() 和 join(),它们是处理文本数据的基础。