#regex #lazy-evaluation #static #compile-time #macro #error-message

no-std lazy-regex

在编译时检查的 lazy 静态正则表达式

20 个稳定版本 (3 个主要版本)

3.3.0 2024 年 8 月 23 日
3.2.0 2024 年 7 月 25 日
3.1.0 2023 年 11 月 9 日
3.0.1 2023 年 7 月 28 日
0.1.2 2019 年 10 月 7 日

#8文本处理

Download history 47091/week @ 2024-05-03 43869/week @ 2024-05-10 44404/week @ 2024-05-17 46797/week @ 2024-05-24 49627/week @ 2024-05-31 51056/week @ 2024-06-07 57226/week @ 2024-06-14 50824/week @ 2024-06-21 51287/week @ 2024-06-28 55160/week @ 2024-07-05 49684/week @ 2024-07-12 52542/week @ 2024-07-19 66179/week @ 2024-07-26 57340/week @ 2024-08-02 54287/week @ 2024-08-09 57105/week @ 2024-08-16

246,929 每月下载量
用于 434 个 crate (184 个直接使用)

MIT 许可证

20KB
99

MIT Latest Version docs Chat on Miaou

lazy-regex

使用 lazy-regex 宏,正则表达式

  • 在编译时进行检查,并提供清晰的错误信息
  • 被包装在 once_cell 懒静态初始化器中,以确保它们只编译一次
  • 可以作为后缀持有标志:let case_insensitive_regex = regex!("ab*"i);
  • 以更简洁的方式定义

regex! 宏返回对 regex::Regexregex::bytes::Regex 的正常实例的引用,因此所有常用功能都是可用的。

其他宏针对测试匹配、使用简洁闭包进行替换或在某些常见情况下将捕获组作为子字符串进行捕获而专门化

  • regex_is_match!
  • regex_find!
  • regex_captures!
  • regex_replace!
  • regex_replace_all!
  • regex_switch!

它们支持 B 标志用于 regex::bytes::Regex 变体。

所有宏都存在一个 bytes_ 前缀,用于构建 bytes::Regex,因此您还有 bytes_regex!bytes_regex_is_match!bytes_regex_find!bytes_regex_captures!bytes_regex_replace!bytes_regex_replace_all!bytes_regex_switch!

regex crate 的一些结构被重新导出以简化依赖关系管理。regex crate 本身也被重新导出,以避免需要同步版本/风味(见下方的 功能

构建正则表达式

use lazy_regex::regex;

// build a simple regex
let r = regex!("sa+$");
assert_eq!(r.is_match("Saa"), false);

// build a regex with flag(s)
let r = regex!("sa+$"i);
assert_eq!(r.is_match("Saa"), true);

// you can use a raw literal
let r = regex!(r#"^"+$"#);
assert_eq!(r.is_match("\"\""), true);

// or a raw literal with flag(s)
let r = regex!(r#"^\s*("[a-t]*"\s*)+$"#i);
assert_eq!(r.is_match(r#" "Aristote" "Platon" "#), true);

// build a regex that operates on &[u8]
let r = regex!("(byte)?string$"B);
assert_eq!(r.is_match(b"bytestring"), true);

// there's no problem using the multiline definition syntax
let r = regex!(r#"(?x)
    (?P<name>\w+)
    -
    (?P<version>[0-9.]+)
"#);
assert_eq!(r.find("This is lazy_regex-2.2!").unwrap().as_str(), "lazy_regex-2.2");
// (look at the regex_captures! macro to easily extract the groups)

// this line doesn't compile because the regex is invalid:
let r = regex!("(unclosed");

支持的正则表达式标志:imsxU

请参阅 regex::RegexBuilder

测试匹配

use lazy_regex::regex_is_match;

let b = regex_is_match!("[ab]+", "car");
assert_eq!(b, true);

提取值

use lazy_regex::regex_find;

let f_word = regex_find!(r#"\bf\w+\b"#, "The fox jumps.");
assert_eq!(f_word, Some("fox"));
let f_word = regex_find!(r#"\bf\w+\b"#B, b"The forest is silent.");
assert_eq!(f_word, Some(b"forest" as &[u8]));

捕获

use lazy_regex::regex_captures;

let (_, letter) = regex_captures!("([a-z])[0-9]+"i, "form A42").unwrap();
assert_eq!(letter, "A");

let (whole, name, version) = regex_captures!(
    r#"(\w+)-([0-9.]+)"#, // a literal regex
    "This is lazy_regex-2.0!", // any expression
).unwrap();
assert_eq!(whole, "lazy_regex-2.0");
assert_eq!(name, "lazy_regex");
assert_eq!(version, "2.0");

元组的尺寸没有限制。编译时会进行检查以确保您有正确数量的捕获组。

对于没有值的可选组,您会收到 ""

使用捕获组进行替换

regex_replace!regex_replace_all! 将一次编译和编译时检查带到 replacereplace_all 函数中。

使用闭包进行替换

use lazy_regex::regex_replace_all;

let text = "Foo8 fuu3";
let text = regex_replace_all!(
    r#"\bf(\w+)(\d)"#i,
    text,
    |_, name, digit| format!("F<{}>{}", name, digit),
);
assert_eq!(text, "F<oo>8 F<uu>3");

传递给闭包的参数数在编译时进行检查,以确保与正则表达式中的组数匹配。

如果不匹配,您将在编译时得到一个清晰的错误信息。

使用另一种类型的 Replacer 进行替换

use lazy_regex::regex_replace_all;
let text = "UwU";
let output = regex_replace_all!("U", text, "O");
assert_eq!(&output, "OwO");

切换正则表达式

执行绑定到第一个匹配正则表达式的表达式,将命名的捕获组声明为变量

use lazy_regex::regex_switch;
pub enum ScrollCommand {
    Top,
    Bottom,
    Lines(i32),
    Pages(i32),
}
impl std::str::FromStr for ScrollCommand {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, ()> {
        regex_switch!(s,
            "^scroll-to-top$" => Self::Top,
            "^scroll-to-bottom$" => Self::Bottom,
            r#"^scroll-lines?\((?<n>[+-]?\d{1,4})\)$"# => Self::Lines(n.parse().unwrap()),
            r#"^scroll-pages?\((?<n>[+-]?\d{1,4})\)$"# => Self::Pages(n.parse().unwrap()),
        ).ok_or(())
    }
}

共享懒静态

当在多个函数中使用正则表达式时,有时您不希望重复使用它,但需要一个共享的静态实例。

regex! 宏虽然在懒静态正则表达式后面,但返回一个引用。

如果您想要一个共享的懒静态正则表达式,请使用 lazy_regex!

use lazy_regex::*;

pub static GLOBAL_REX: Lazy<Regex> = lazy_regex!("^ab+$"i);

与其他宏一样,正则表达式是静态的,在编译时进行检查,并在首次使用时懒加载。

功能和重新导出

默认功能下,lazy-regex 使用 regex crate,具有默认功能,针对性能和完整的 Unicode 支持进行了优化。

您可以直接在导入 lazy-regex 时启用它们来启用不同的正则表达式功能集。

您也可以通过声明 lite 功能来使用 regex-lite crate 代替 regex crate。

lazy-regex = { version = "3.0", default-features = false, features = ["lite"] }

lite 风味具有略低的性能和减少的 Unicode 支持(请参阅 crate 文档),但二进制尺寸更小。

如果您需要在代码中引用正则表达式 crate,请优先使用重新导出(即 use lazy_regex::regex;),这样您就不会有版本或风味冲突。当启用 lite 功能时,lazy_regex::regex 将引用 regex_lite,因此在切换正则表达式引擎时无需更改您的代码。

依赖关系

~2.5–4MB
~74K SLoC