create_capture!() { /* proc-macro */ }
Expand description
A macro to create a Regular Expression capturing struct.
This macro will create an helper struct for capture regular expression groups for a hard coded regular expression.
The macro has two arguments, the first one should be the name of the struct to create and the second one is the regular expression, either as raw regular expression or as a DSL (See regex_dsl! for syntax).
The struct will be a tuple with the first filed as a &str
with the entire capture text (i.e. capture group 0) and the rest will be
Option<&str>
with the content of the capture group (for any capture group in the regular expression). That is, for [a-z]+
the struct will have
only (&str)
and for ([a-z]+)([0-9]+)([a-z]+)
the struct will have (&str, Option<&str>, Option<&str>, Option<&str>)
. If the regular expression has any named
capture groups, the struct will have a public function to retrieve them with the same name as the group name (snake case). The struct will have a get_capture
method that will return the first member of the tuple.
The struct will have three static public functions:
catch
that accept a string reference and return an Option with the struct if it matches the argument.catch_all
that accept a string reference and return an Iterator over all the places the expression was caught in the argument.regex
that return a reference to the regular expression.
Please note, The capturing groups are optionals for regular expressions like: ([a-z]+)|([0-9]+)
.
For example:
use rust_regex_dsl::create_capture;
create_capture!(MyRegexCapture, "([0-9]+)");
assert!(MyRegexCapture::catch("Foo").is_none());
let caught = MyRegexCapture::catch("33").unwrap();
assert_eq!(caught.0, "33");
assert_eq!(caught.get_capture(), "33");
assert_eq!(caught.1, Some("33"));
let all: Vec<_> = MyRegexCapture::catch_all("100 90 80").collect();
assert_eq!(all.len(), 3);
assert_eq!(all[0].0, "100");
assert_eq!(all[1].0, "90");
assert_eq!(all[2].0, "80");
A more complex example:
use rust_regex_dsl::create_capture;
create_capture!(MyRegexCapture,
any {
group {
name: Letters,
repeat {
any_of {
#letter
}
}
}, group {
name: Digits,
repeat {
any_of {
#digit
}
}
}
});
let caught = MyRegexCapture::catch("hello").unwrap();
assert_eq!(caught.0, "hello");
assert_eq!(caught.get_capture(), "hello");
assert_eq!(caught.1, Some("hello"));
assert_eq!(caught.letters(), Some("hello"));
assert_eq!(caught.2, None);
assert_eq!(caught.digits(), None);
let caught = MyRegexCapture::catch("321").unwrap();
assert_eq!(caught.0, "321");
assert_eq!(caught.get_capture(), "321");
assert_eq!(caught.1, None);
assert_eq!(caught.letters(), None);
assert_eq!(caught.2, Some("321"));
assert_eq!(caught.digits(), Some("321"));
let all: Vec<_> = MyRegexCapture::catch_all("A1234B33").collect();
assert_eq!(all.len(), 4);
assert_eq!(all[0].1, Some("A"));
assert_eq!(all[1].2, Some("1234"));
assert_eq!(all[2].letters(), Some("B"));
assert_eq!(all[3].digits(), Some("33"));