Julia 字符串(String)完全指南(中文版)
“强大、原生 UTF-8、零成本操作” —— Julia 的字符串设计极致优雅
一、字符串基础
1. 创建字符串
s1 = "Hello, Julia!" # 双引号
s2 = "中文支持很好" # 完全支持 Unicode
s3 = """多行
字符串""" # 三引号支持换行
2. 单引号 vs 双引号
| 类型 | 含义 |
|---|---|
'A' | Char 类型(单个字符) |
"A" | String 类型(字符串) |
typeof('A') # Char
typeof("A") # String
二、字符串插值(Interpolation)
name = "Alice"
age = 25
"Hi, $name! You are $age years old." # → "Hi, Alice! You are 25 years old."
# 表达式插值
"2 + 3 = $(2+3)" # → "2 + 3 = 5"
"π ≈ $(round(π, digits=4))" # → "π ≈ 3.1416"
三、字符串连接
# 方法1:*
s1 = "Hello"
s2 = "World"
s1 * ", " * s2 * "!" # "Hello, World!"
# 方法2:string()
string(s1, ", ", s2, "!")
# 方法3:join()
join(["a", "b", "c"], "-") # "a-b-c"
四、常用字符串函数
| 函数 | 说明 | 示例 |
|---|---|---|
length(s) | 字符数(非字节) | length("中文") → 2 |
sizeof(s) | 字节数(UTF-8) | sizeof("中文") → 6 |
uppercase(s) | 转大写 | |
lowercase(s) | 转小写 | |
titlecase(s) | 首字母大写 | |
split(s, delim) | 按分隔符切分 | split("a,b,c", ",") → ["a","b","c"] |
strip(s) | 去首尾空白 | |
replace(s, old=>new) | 替换 | replace("hello", "l"=>"x") → "hexxo" |
occursin(needle, haystack) | 子串判断 | |
startswith(s, prefix) | 前缀判断 | |
endswith(s, suffix) | 后缀判断 |
length("你好👋") # 3(字符数)
sizeof("你好👋") # 10(字节数)
五、字符(Char)操作
c = '中'
codepoint(c) # 20013(Unicode 码点)
Int(c) # 20013
Char(65) # 'A'
# 遍历字符串(自动按字符)
for c in "Julia"
println(c)
end
六、字符串索引(按字符,非字节!)
s = "Julia编程"
s[1] # 'J'
s[2] # 'u'
s[end] # '程'
s[end-1] # '编'
# 切片(返回 SubString,零拷贝!)
s[1:5] # "Julia"
s[6:end] # "编程"
注意:不能用
s[1] = 'X'修改(字符串不可变)
七、SubString —— 零成本切片
s = "性能测试:SubString 零拷贝"
sub = SubString(s, 7, 12) # "SubString"
- 不复制内存
- 共享原字符串数据
- 性能极高
八、正则表达式(Regex)
# 创建正则
r = r"^\d{4}-\d{2}-\d{2}$" # 匹配日期
r"julia"i # 忽略大小写
# 匹配
occursin(r"hello", "Hello World") # true
match(r"(\w+)@(\w+\.\w+)", "abc@example.com")
# → RegexMatch("abc@example.com", 1="abc", 2="example.com")
# 替换
replace("x=1, y=2", r"\w+" => "num") # "num=num, num=num"
# 搜索所有
collect(eachmatch(r"\w+", "a b c")) # 3个匹配
九、字符串与数组互转
# 字符串 → 字符数组
collect("Julia") # ['J', 'u', 'l', 'i', 'a']
# 数组 → 字符串
join(['a', 'b', 'c'], "") # "abc"
string("a", "b", "c") # "abc"
十、格式化输出(@sprintf, Printf)
using Printf
@sprintf("π ≈ %.4f", π) # "π ≈ 3.1416"
@sprintf("x = %10d", 42) # "x = 42"
@sprintf("hex: 0x%08x", 255) # "hex: 0x000000ff"
十一、性能技巧
1. 字符串连接优化
# 慢:动态增长
result = ""
for i in 1:10000
result *= string(i)
end
# 快:预分配 String 构建器
result = IOBuffer()
for i in 1:10000
print(result, i)
end
String(take!(result))
2. 用 SubString 避免复制
function parse_line(line)
# line: "name,age,city"
parts = split(line, ',')
return SubString(line, 1, findfirst(',', line)-1) # 零拷贝
end
十二、综合示例:CSV 解析器(轻量版)
function parse_csv_line(line::AbstractString)
fields = String[]
start = 1
in_quotes = false
for i in eachindex(line)
c = line[i]
if c == '"'
in_quotes = !in_quotes
elseif c == ',' && !in_quotes
push!(fields, SubString(line, start, i-1))
start = i + 1
end
end
push!(fields, SubString(line, start, lastindex(line)))
return fields
end
line = """Alice,25,"Beijing, China",true"""
parse_csv_line(line)
# → ["Alice", "25", "\"Beijing, China\"", "true"]
十三、字符串速查表
| 操作 | 语法 |
|---|---|
| 创建 | "text", """multi\nline""" |
| 插值 | "$var", "$(f(x))" |
| 连接 | *, string(), join() |
| 长度 | length(s)(字符), sizeof(s)(字节) |
| 索引 | s[1], s[end] |
| 切片 | s[1:5] → SubString |
| 替换 | replace(s, old=>new) |
| 正则 | r"pattern", match(), eachmatch() |
| 格式化 | @sprintf, Printf |
十四、小练习(立即上手)
- 将
"hello world"转为"Hello World"(每个单词首字母大写) - 写函数统计字符串中每个字符出现次数(用
Dict) - 用正则提取所有邮箱地址
- 实现
reverse(s)反转字符串 - 性能对比:
*vsStringVector连接 1万次
答案示例
# 1. 单词首字母大写
titlecase_words(s) = join(titlecase.(split(s)), " ")
titlecase_words("hello world") # "Hello World"
# 2. 字符计数
function char_count(s)
counts = Dict{Char, Int}()
for c in s
counts[c] = get(counts, c, 0) + 1
end
return counts
end
# 3. 提取邮箱
emails = [m.match for m in eachmatch(r"\b[\w.-]+@[\w.-]+\.\w+\b", text)]
# 4. 反转字符串
myreverse(s) = join(reverse(collect(s)))
myreverse("Julia") # "ailuJ"
# 5. 性能测试
using BenchmarkTools
@btime begin
s = ""
for i in 1:10_000
s *= "a"
end
end
@btime begin
buf = IOBuffer()
for i in 1:10_000
print(buf, "a")
end
String(take!(buf))
end
十五、常见错误与避坑
| 错误 | 正确做法 |
|---|---|
s[1] = 'X' | 字符串不可变!用 replace 或重建 |
length(s) 算字节 | 中文 1 字 = 1 字符,length 正确 |
"a" + "b" | Julia 无 + 字符串,用 * |
match(r"a", "b") 返回 nothing | 检查是否 nothing |
恭喜!你已精通 Julia 字符串!
现在你可以:
- 流畅处理中文、多语言
- 实现高性能文本解析
- 写出优雅的格式化输出
- 轻松使用正则表达式
下一站推荐
| 主题 | 为什么学 |
|---|---|
Symbol | 轻量标识符 |
IO 与文件读写 | 文本处理 |
CSV.jl / DataFrames | 数据导入 |
JSON.jl | 数据交换 |
HTTP.jl | 网络请求 |
需要我:
- 写一个 日志格式化工具?
- 实现 模板引擎(类似 Mustache)?
- 构建 CSV 读取器(零分配)?
- 演示 Unicode 规范化?
随时告诉我!