MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Rust字符串实用函数的使用指南

2022-10-184.4k 阅读

Rust字符串基础概念

在Rust中,字符串相关类型主要有&strString&str是字符串切片,它是一个指向UTF - 8编码字符串数据的不可变引用,通常以字面量形式出现,例如let s: &str = "hello";String则是一个可增长、可改变的字符串类型,它拥有数据的所有权,例如let mut s = String::from("world");

字符串创建函数

  1. String::from
    • 本质:这是一个从字符串字面量创建String类型的方法。它会把字符串字面量的数据复制到新分配的String对象中。
    • 代码示例
let s = String::from("hello");
println!("The string is: {}", s);
  1. String::new
    • 本质:创建一个新的空String。后续可以通过其他方法向这个空字符串中添加内容。
    • 代码示例
let mut s = String::new();
s.push('a');
println!("The string is: {}", s);
  1. format!
    • 本质:类似于C语言中的printf函数,它允许根据格式化字符串和参数创建一个新的String。它会分配新的内存来存储格式化后的字符串。
    • 代码示例
let num = 42;
let s = format!("The number is {}", num);
println!("The string is: {}", s);

字符串拼接函数

  1. push
    • 本质:用于向String类型的字符串末尾添加一个字符。它修改了调用它的String对象本身。
    • 代码示例
let mut s = String::from("hel");
s.push('l');
s.push('o');
println!("The string is: {}", s);
  1. push_str
    • 本质:将一个字符串切片追加到String的末尾。与push不同,它接受的是一个字符串切片(&str),并且同样修改调用它的String对象。
    • 代码示例
let mut s1 = String::from("Hello");
let s2 = " World";
s1.push_str(s2);
println!("The string is: {}", s1);
  1. +运算符
    • 本质:用于连接两个String。它会把右侧的String移动到左侧的String后面,并返回结果String。在连接过程中,左侧的String会被消耗掉。
    • 代码示例
let s1 = String::from("Hello");
let s2 = String::from(" World");
let s3 = s1 + &s2;
// 这里s1已经不能再使用,因为它被移动到了s3中
println!("The string is: {}", s3);
  1. format!宏拼接
    • 本质:通过format!宏,可以在格式化字符串中包含多个变量和字符串,从而实现拼接效果。与+运算符不同,它不会消耗任何原有的String对象。
    • 代码示例
let s1 = String::from("Hello");
let s2 = String::from(" World");
let s3 = format!("{}{}", s1, s2);
// s1和s2仍然可以继续使用
println!("The string is: {}", s3);

字符串长度相关函数

  1. len
    • 本质:返回字符串的字节长度。需要注意的是,由于Rust字符串是UTF - 8编码,一个字符可能占用多个字节,所以len返回的不是字符个数。
    • 代码示例
let s = String::from("Hello");
println!("The length of the string is: {}", s.len());
  1. charscount
    • 本质chars方法将字符串拆分成一个个字符的迭代器,count方法用于统计迭代器中的元素个数。结合这两个方法可以得到字符串的字符个数。
    • 代码示例
let s = String::from("你好");
let char_count = s.chars().count();
println!("The character count of the string is: {}", char_count);

字符串查找函数

  1. contains
    • 本质:检查字符串是否包含指定的子字符串。它会从字符串的开头开始搜索,直到找到匹配的子字符串或者到达字符串末尾。
    • 代码示例
let s = String::from("Hello, world!");
let contains_substring = s.contains("world");
println!("Does the string contain 'world'? {}", contains_substring);
  1. starts_with
    • 本质:判断字符串是否以指定的子字符串开头。
    • 代码示例
let s = String::from("Hello, world!");
let starts_with_hello = s.starts_with("Hello");
println!("Does the string start with 'Hello'? {}", starts_with_hello);
  1. ends_with
    • 本质:判断字符串是否以指定的子字符串结尾。
    • 代码示例
let s = String::from("Hello, world!");
let ends_with_world = s.ends_with("world!");
println!("Does the string end with 'world!'? {}", ends_with_world);
  1. find
    • 本质:查找指定子字符串在字符串中的第一次出现位置,并返回其索引。如果未找到,则返回None
    • 代码示例
let s = String::from("Hello, world!");
if let Some(index) = s.find("world") {
    println!("The index of 'world' is: {}", index);
} else {
    println!("'world' not found.");
}
  1. rfind
    • 本质:与find类似,但它是从字符串的末尾开始查找指定子字符串的最后一次出现位置,并返回其索引。如果未找到,则返回None
    • 代码示例
let s = String::from("banana");
if let Some(index) = s.rfind("na") {
    println!("The index of the last 'na' is: {}", index);
} else {
    println!("'na' not found.");
}

字符串替换函数

  1. replace
    • 本质:将字符串中所有匹配的子字符串替换为指定的新字符串。它会创建一个新的String对象,原字符串保持不变。
    • 代码示例
let s = String::from("Hello, world!");
let new_s = s.replace("world", "Rust");
println!("The new string is: {}", new_s);
  1. replacen
    • 本质:与replace类似,但它可以指定替换的次数。同样会创建一个新的String对象。
    • 代码示例
let s = String::from("banana");
let new_s = s.replacen("na", "XY", 1);
println!("The new string is: {}", new_s);

字符串分割函数

  1. split
    • 本质:以指定的分隔符将字符串分割成多个子字符串,并返回一个迭代器。每个子字符串不包含分隔符。
    • 代码示例
let s = String::from("Hello,world,Rust");
for part in s.split(',') {
    println!("Part: {}", part);
}
  1. splitn
    • 本质:与split类似,但它可以指定最多分割的次数。返回的迭代器会包含分割后的子字符串。
    • 代码示例
let s = String::from("a,b,c,d");
let parts: Vec<&str> = s.splitn(3, ',').collect();
for part in parts {
    println!("Part: {}", part);
}
  1. rsplit
    • 本质:从字符串的末尾开始,以指定的分隔符将字符串分割成多个子字符串,并返回一个迭代器。
    • 代码示例
let s = String::from("Hello,world,Rust");
for part in s.rsplit(',') {
    println!("Part: {}", part);
}
  1. rsplitn
    • 本质:从字符串的末尾开始,最多分割指定次数,并返回一个迭代器。
    • 代码示例
let s = String::from("a,b,c,d");
let parts: Vec<&str> = s.rsplitn(3, ',').collect();
for part in parts {
    println!("Part: {}", part);
}
  1. split_once
    • 本质:以指定的分隔符将字符串分割一次,返回一个包含两个元素的元组,第一个元素是分隔符左边的部分,第二个元素是分隔符右边的部分。如果未找到分隔符,则返回None
    • 代码示例
let s = String::from("Hello,world");
if let Some((left, right)) = s.split_once(',') {
    println!("Left: {}, Right: {}", left, right);
} else {
    println!("Separator not found.");
}
  1. rsplit_once
    • 本质:从字符串的末尾开始,以指定的分隔符将字符串分割一次,返回一个包含两个元素的元组。如果未找到分隔符,则返回None
    • 代码示例
let s = String::from("Hello,world");
if let Some((left, right)) = s.rsplit_once(',') {
    println!("Left: {}, Right: {}", left, right);
} else {
    println!("Separator not found.");
}

字符串转换函数

  1. to_lowercase
    • 本质:将字符串中的所有字符转换为小写形式,并返回一个新的String。原字符串保持不变。
    • 代码示例
let s = String::from("HELLO");
let lower_s = s.to_lowercase();
println!("The lowercase string is: {}", lower_s);
  1. to_uppercase
    • 本质:将字符串中的所有字符转换为大写形式,并返回一个新的String。原字符串保持不变。
    • 代码示例
let s = String::from("hello");
let upper_s = s.to_uppercase();
println!("The uppercase string is: {}", upper_s);
  1. parse
    • 本质:将字符串解析为其他类型,例如i32f64等。如果解析失败,会返回一个Err值。
    • 代码示例
let s = String::from("42");
if let Ok(num) = s.parse::<i32>() {
    println!("The parsed number is: {}", num);
} else {
    println!("Failed to parse.");
}
  1. to_string
    • 本质:将实现了Display trait的类型转换为String。例如,整数、浮点数等都可以通过to_string方法转换为字符串。
    • 代码示例
let num = 42;
let s = num.to_string();
println!("The string is: {}", s);

字符串修剪函数

  1. trim
    • 本质:去除字符串两端的空白字符(空格、制表符、换行符等),并返回一个新的字符串切片(&str)。原字符串保持不变。
    • 代码示例
let s = String::from("   Hello   ");
let trimmed_s = s.trim();
println!("The trimmed string is: '{}'", trimmed_s);
  1. trim_start
    • 本质:去除字符串开头的空白字符,并返回一个新的字符串切片(&str)。
    • 代码示例
let s = String::from("   Hello   ");
let trimmed_s = s.trim_start();
println!("The trimmed string is: '{}'", trimmed_s);
  1. trim_end
    • 本质:去除字符串末尾的空白字符,并返回一个新的字符串切片(&str)。
    • 代码示例
let s = String::from("   Hello   ");
let trimmed_s = s.trim_end();
println!("The trimmed string is: '{}'", trimmed_s);
  1. trim_matches
    • 本质:去除字符串两端所有匹配指定字符的字符,并返回一个新的字符串切片(&str)。
    • 代码示例
let s = String::from("***Hello***");
let trimmed_s = s.trim_matches('*');
println!("The trimmed string is: '{}'", trimmed_s);
  1. trim_start_matches
    • 本质:去除字符串开头所有匹配指定字符的字符,并返回一个新的字符串切片(&str)。
    • 代码示例
let s = String::from("***Hello***");
let trimmed_s = s.trim_start_matches('*');
println!("The trimmed string is: '{}'", trimmed_s);
  1. trim_end_matches
    • 本质:去除字符串末尾所有匹配指定字符的字符,并返回一个新的字符串切片(&str)。
    • 代码示例
let s = String::from("***Hello***");
let trimmed_s = s.trim_end_matches('*');
println!("The trimmed string is: '{}'", trimmed_s);

字符串比较函数

  1. eq
    • 本质:比较两个字符串是否相等。它会逐个字符地比较字符串内容,区分大小写。
    • 代码示例
let s1 = String::from("Hello");
let s2 = String::from("Hello");
let is_equal = s1.eq(&s2);
println!("Are the strings equal? {}", is_equal);
  1. cmp
    • 本质:按照字典序比较两个字符串。它返回一个Ordering枚举值,表示比较结果(小于、等于、大于)。
    • 代码示例
let s1 = String::from("apple");
let s2 = String::from("banana");
let result = s1.cmp(&s2);
match result {
    std::cmp::Ordering::Less => println!("s1 is less than s2"),
    std::cmp::Ordering::Equal => println!("s1 is equal to s2"),
    std::cmp::Ordering::Greater => println!("s1 is greater than s2"),
}
  1. starts_withends_with用于比较开头和结尾
    • 本质:这两个函数在前面查找部分已经介绍过,但它们也可以看作是一种特殊的比较。starts_with比较字符串开头部分是否匹配,ends_with比较字符串结尾部分是否匹配。
    • 代码示例
let s = String::from("Hello, world!");
let starts_with_hello = s.starts_with("Hello");
let ends_with_world = s.ends_with("world!");
println!("Starts with 'Hello': {}", starts_with_hello);
println!("Ends with 'world!': {}", ends_with_world);

字符串迭代函数

  1. chars
    • 本质:将字符串拆分成一个个字符的迭代器。通过这个迭代器可以方便地遍历字符串中的每个字符。
    • 代码示例
let s = String::from("Hello");
for c in s.chars() {
    println!("Character: {}", c);
}
  1. bytes
    • 本质:将字符串拆分成一个个字节的迭代器。由于Rust字符串是UTF - 8编码,通过这个迭代器可以访问字符串的底层字节表示。
    • 代码示例
let s = String::from("Hello");
for byte in s.bytes() {
    println!("Byte: {}", byte);
}
  1. lines
    • 本质:将字符串按行分割,并返回一个迭代器,每个元素是一行字符串(不包含换行符)。这在处理多行文本时非常有用。
    • 代码示例
let s = String::from("Line 1\nLine 2\nLine 3");
for line in s.lines() {
    println!("Line: {}", line);
}

字符串格式化函数

  1. format_args!系列宏
    • 本质format_args!write!writeln!等宏用于更灵活的字符串格式化。format_args!创建一个Arguments结构体,包含格式化信息;write!writeln!将格式化后的内容写入实现了Write trait的对象(如String)。
    • 代码示例
use std::fmt::Write;

let mut s = String::new();
let num = 42;
write!(&mut s, "The number is {}", num).unwrap();
println!("The string is: {}", s);
  1. format!宏的高级格式化
    • 本质format!宏支持各种格式化选项,如指定宽度、精度等。例如,格式化浮点数时可以指定小数位数。
    • 代码示例
let num = 3.1415926;
let s = format!("The number with 2 decimal places is: {:.2}", num);
println!("The string is: {}", s);

字符串内存管理相关函数

  1. into_bytes
    • 本质:将String转换为Vec<u8>,获取字符串的字节表示,并消耗掉原String对象。
    • 代码示例
let s = String::from("Hello");
let bytes = s.into_bytes();
for byte in bytes {
    println!("Byte: {}", byte);
}
  1. from_utf8from_utf8_lossy
    • 本质from_utf8尝试将Vec<u8>转换为Result<String>,如果字节序列是有效的UTF - 8编码,则返回Ok(String),否则返回Errfrom_utf8_lossy则是一种“宽容”的转换,它会将无效的UTF - 8字节序列替换为(Unicode替换字符),并返回一个Cow<'a, str>类型,可能是借用的字符串切片(如果输入是有效的UTF - 8),也可能是新分配的String
    • 代码示例
let valid_bytes = b"Hello".to_vec();
if let Ok(s) = String::from_utf8(valid_bytes) {
    println!("The string is: {}", s);
} else {
    println!("Invalid UTF - 8");
}

let invalid_bytes = vec![65, 66, 255, 68];
let s = std::str::from_utf8_lossy(&invalid_bytes);
println!("The string is: {}", s);

通过深入理解和灵活运用这些Rust字符串实用函数,开发者能够更加高效地处理字符串相关的操作,无论是在简单的文本处理还是复杂的应用开发中,都能充分发挥Rust语言在字符串处理方面的强大能力。