2 个稳定版本

1.1.0 2022年6月5日
1.0.0 2021年4月24日

#16 in #array-string

Download history 51/week @ 2024-03-11 26/week @ 2024-03-18 31/week @ 2024-03-25 57/week @ 2024-04-01 33/week @ 2024-04-08 35/week @ 2024-04-15 44/week @ 2024-04-22 28/week @ 2024-04-29 60/week @ 2024-05-06 87/week @ 2024-05-13 133/week @ 2024-05-20 82/week @ 2024-05-27 150/week @ 2024-06-03 43/week @ 2024-06-10 26/week @ 2024-06-17 31/week @ 2024-06-24

263 每月下载量
用于 2 crates

BSD-3-Clause

57KB
1.5K SLoC

proc-macro-regex

一个进程宏正则表达式库,用于匹配任意字符串或字节数组与正则表达式。 构建状态 最新版本 依赖状态 许可

用法

将其添加到您的 Cargo.toml

[dependencies]
proc-macro-regex = "~1.1.0"

示例

regex! 创建一个具有给定名称的函数,该函数接受一个字符串或字节数组,如果参数与正则表达式匹配则返回 true,否则返回 false

use proc_macro_regex::regex;

/// Create the function with the signature:
/// fn regex_email(s: &str) -> bool; 
regex!(regex_email "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$");

fn main () {
   println!("Returns true  == {}", regex_email("[email protected]"));
   println!("Returns false == {}", regex_email("example.example.org"));
}

给定的正则表达式与 regex crate 中的正则表达式的工作方式相同。如果正则表达式以 ^ 开头并以 $ 结尾,则检查整个字符串,否则检查字符串中是否包含正则表达式。

它如何工作

该宏创建一个 确定性有限自动机 (DFA),解析给定的输入。根据 DFA 的大小或正则表达式的字符,生成查找表或基于代码的实现(二分查找)。如果查找表的大小大于 65536 字节(可以更改)则使用基于代码的实现(二分查找)。此外,如果正则表达式包含任何 Unicode(非 ASCII)字符,则也使用基于代码的实现(二分查找)。

以下宏生成以下代码

regex!(example_1 "abc");

生成

fn example_1(s: &str) -> bool {
    static TABLE: [[u8; 256]; 3usize] = [ ... ];
    let mut state = 0;
    for c in s.bytes() {
        state = TABLE[state as usize][c as usize];
        if state == u8::MAX {
            return true;
        }
    }
    false
}

要告诉宏查找表的大小不允许超过 256 字节,可以提供第三个参数。因此,生成基于代码的 DFA 实现(二分查找)。

regex!(example_2 "abc" 256);

生成

fn example_2(s: &str) -> bool {
    let mut state = 0;
    for c in s.bytes() {
        state = if state < 1usize {
            match c {
                97u8 => 1usize,
                _ => 0usize,
            }
        } else {
            if state == 1usize {
                match c {
                    97u8 => 1usize,
                    98u8 => 2usize,
                    _ => 0usize,
                }
            } else {
                match c {
                    97u8 => 1usize,
                    99u8 => return true,
                    _ => 0usize,
                }
            }
        };
    }
    false
}

要更改函数的可见性,请在参数开头添加关键词。

regex!(pub example_2 "abc" 256);

生成

pub fn example_3(s: &str) -> bool {
   // same as in example_1 (see above)
}

要解析字节数组而不是字符串,请传递字节字符串。

regex!(example_4 b"abc");

生成

fn example_4(s: &[u8]) -> bool {
   // same as in example_1 (see above)
}

生成的代码也应与#![no_std]兼容。

proc-macro-regex 与 regex

优点

  • 编译时(无需运行时初始化,无需懒加载静态内容)
  • 生成的代码不包含任何依赖
  • 无堆分配
  • 对于无琐碎正则表达式,速度提高约12%-68% [^1]

[^1]: 在benches/compare.rs中与regex进行了测试。由于regex库使用aho-corasick,对于模式/单词匹配它较慢。(见性能)

缺点

  • 目前,没有组捕获
  • 无运行时正则表达式生成

性能

这是此crate与regex crate之间的性能比较。如果您想自己测试,请运行cargo bench --bench compare

名称 proc-macro-regex regex 结果
电子邮件 743.95 MiB/s 441.67 MiB/s 68.44 %
URL 584.62 MiB/s 519.00 MiB/s 12.64 %
IPv6 746.92 MiB/s 473.38 MiB/s 57.78 %

这是使用rustc 1.53.0-nightly (392ba2ba1 2021-04-17)编译的。

许可证

本项目采用BSD-3-Clause许可证。

贡献

您有意提交到proc-macro-regex的任何贡献,均应作为BSD-3-Clause许可,不得附加任何额外条款或条件。

依赖项

~2.5MB
~67K SLoC