#regex #readable #meta #multi-language #easy

easy-regex

将长正则表达式写成类似伪代码的形式

1 个不稳定版本

0.11.7 2022年3月27日
0.10.6 2022年3月24日
0.7.4 2022年3月14日
0.1.1 2022年3月11日

#634 in 文本处理

MIT 许可证

92KB
2K SLoC

build docs tests license

用法

这个轻量级包可以帮助您将长正则表达式写成尽可能可读的形式,通过使重要部分详尽并为您提供方便编写/阅读表达式的选项。它与 regex 包结合使用。

简介

它由三个主要方法和许多实用函数组成。除了已调整的标志、特殊字符和准备好的模式(如网站 URL、日期/时间格式、法语、波斯语、中文字母表等)的组合外,您还可以编写易于跟随和阅读的长正则表达式。

主要功能

主要函数有 literallistgroup。它们通过链式调用协同工作,接受两个参数,一个用于表达式,另一个用于特殊字符、标志等。

简单正则表达式

要创建类似以下正则表达式

r"(?i)(?-i:Don't capture)\s(me)";

可以使用此包如下所示

use easy_regex::{EasyRegex, settings::{base:: DEFAULT, group::{DEFAULT_GROUP, SENSITIVE_NON_CAPTURE}}};

let text = "Don't capture ME";  // a text to be matched by our regex.
let result = EasyRegex::insensitive()
    .group("Don't capture", &SENSITIVE_NON_CAPTURE) // SENSITIVE_NON_CAPTURE refers to  
                                                    // (?-i) and (?: ...) options which  
                                                    // together makes the (?-i: ...) pattern.
    .whitespace(&DEFAULT)
    .group(r"me", &DEFAULT_GROUP);

let captured_text = result.clone().get_regex().unwrap()
    .captures(text).unwrap().get(1).unwrap().as_str();

    assert_eq!(r"(?i)(?-i:Don't capture)\s(me)", result.get_regex().unwrap().as_str());
    assert_eq!("ME", captured_text); // insensitive ME

长正则表达式

对于

r"^(http|https|ftp):/{2}([a-zA-Z0-9-.]+\.[a-zA-Z]{2,4})(:[0-9]+)?/?([a-zA-Z0-9-._?,'/\\+&%$#=~]*)";

它将是

use easy_regex::{
    EasyRegex, 
    settings::{Settings, base::*, group::*},
    collection::{ALPHA_NUMERIC, UPPER_LOWER_CASE}
    };

let section_one = EasyRegex::start_of_line()
    .group(r"http|https|ftp", &DEFAULT_GROUP)
    .literal(":", &DEFAULT)
    .literal(r"/", &Settings::exactly(2));

let section_two = EasyRegex::new_section()
    .list(r"a-zA-Z0-9-.", &ONE_OR_MORE)
    .literal(r"\.", &DEFAULT)
    .list(
        &UPPER_LOWER_CASE,
        &Settings::range(Some(2), Some(4))
    )
    .into_group(&DEFAULT)  // put all previous patterns of "section_two" into a group with default options 
                           // i.e. a capturing group like (previous patterns)
    .group(":[0-9]+", &OPTIONAL_GROUP)
    .literal(r"/", &OPTIONAL);

let section_three = EasyRegex::new_section()
    .literal(&ALPHA_NUMERIC, &DEFAULT)
    .literal(r"-._?,'/\\+&%$#=~", &DEFAULT) // special characters need not be scaped
                                                // due to the next method, into_list.
    .into_list(&NIL_OR_MORE)
    .into_group(&DEFAULT);

let collected_sections = format!(
    "{}{}{}",
    section_one.get_regex().unwrap(),
    section_two.get_regex().unwrap(),
    section_three.get_regex().unwrap()
);

let is_result_ok = regex::RegexBuilder::new(&collected_sections).build().is_ok();
assert_eq!(true, is_result_ok);

有一些用于复杂模式(如网站 URL、日期/时间格式、非英语字母表等)的正则表达式。以下是几个示例。

日期和时间正则表达式

use easy_regex::{
    EasyRegex, 
    settings::{Settings, group::DEFAULT_GROUP},
    collection::{DATE, TIME_HH_MM_24}
    };

let text = r#"
    Feb 17 2009 5:3am 03/26/1994 8:41 23/7/2030 9:20Pm
    12 Sept 2015 6:14 03-26-1994 02:18 2030/4/27 3:50
"#;
let result = EasyRegex::new_section()
    .group(DATE, &DEFAULT_GROUP)   // will capture any valid format of a date.
    .literal_space()
    .group(TIME_HH_MM_24, &DEFAULT_GROUP);  // will capture hours and minutes in 24-hour clock.
result
    .clone()
    .get_regex()
    .unwrap()
    .captures_iter(text)
    .for_each(|captures| println!("{}", captures.get(0).unwrap().as_str()));
    // The captures will be:
    //   03/26/1994 8:41
    //   12 Sept 2015 6:14
    //   03-26-1994 02:18
    //   2030/4/27 3:50

let matched_patterns_count = result.get_regex().unwrap().captures_iter(text).count();
assert_eq!(4, matched_patterns_count);

法语正则表达式

对于其他语言(包括法语)也有有用的正则表达式集合。

use easy_regex::{EasyRegex, collection::FRENCH_ALPHABET, settings::base::ONE_OR_MORE};

let text = "Adélaïde Aurélie";
let result = EasyRegex::new_section().list(&FRENCH_ALPHABET, &ONE_OR_MORE);

let count = result.get_regex().unwrap().captures_iter(text).count();
assert_eq!(2, count);

为了使生活更简单,还有创建某些表达式的方法,例如可以具有子元素 HTML 元素。请参阅 辅助函数

依赖关系

~2.2–3MB
~54K SLoC