使用正则表达式匹配字符串比遍历每个变体名称并尝试在目标字符串中将其作为子字符串查找更有效。我整理了一个示例,说明如何使用 strum 和 regex 板条箱完成此操作。
具有一长串变体的枚举,以及一组要搜索的目标字符串。
use std::str::FromStr;
use lazy_static::lazy_static;
use regex::Regex;
use strum::{EnumString, EnumVariantNames, VariantNames};
#[derive(EnumString, EnumVariantNames, Debug)]
enum Thing {
Foo,
Bar,
Baz,
Qux,
Quux,
Quuz,
Corge,
Grault,
Garply,
Waldo,
Fred,
Plugh,
Xyzzy,
Thud,
}
// Target strings to look for variant names in.
//
static STRINGS: [&str; 10] = [
"fdskQuuzjfkds", "fkjdFoo", "Fred", "fkdXyzzy", "Plughfkdjs",
"QuuxQuux", "GraultGarply", "TTTThud", "CCorgee", "Waldo",
];
将正则表达式设置为只需要在运行时编译一次的静态表达式。它由strum crate 功能提供的变体名称构成。
lazy_static! {
// A Regular Expression used to find variant names in target strings.
//
static ref THING_EXPR: Regex = {
// Piece together the expression from Thing's variant names.
let expr_str = Thing::VARIANTS.join("|");
Regex::new(&expr_str).unwrap()
};
}
显示如何迭代字符串集以及检测和处理变体的示例代码。首先捕获变体名称,然后从表达式结果中提取,然后使用字符串检索枚举的同名变体。
fn main() {
for target in STRINGS {
if let Some(captures) = THING_EXPR.captures(target) {
// Get the substring that matched one of the variants.
let variant_name = &captures[0];
// Convert the string to the actual variant.
let variant = Thing::from_str(variant_name).unwrap();
println!("variant name: {:<8} -- variant: {:?}",
variant_name, variant);
}
}
}
将这些依赖项添加到 Cargo.toml 文件中:
[dependencies]
lazy_static = "1.4"
strum = { version = "0.21", features = ["derive"] }
regex = "1.5"
输出:
variant name: Quuz -- variant: Quuz
variant name: Foo -- variant: Foo
variant name: Fred -- variant: Fred
variant name: Xyzzy -- variant: Xyzzy
variant name: Plugh -- variant: Plugh
variant name: Quux -- variant: Quux
variant name: Grault -- variant: Grault
variant name: Thud -- variant: Thud
variant name: Corge -- variant: Corge
variant name: Waldo -- variant: Waldo