pub struct ExpressionSet<'a> { /* private fields */ }
compiler
only.Expand description
Collection of regular expressions.
This is the main entry point to vectorscan’s primary functionality: matching against sets of patterns at once, which is typically poorly supported or less featureful than single-pattern matching in many other regex engines.
This struct provides an immutable (returning Self
) builder interface
to attach additional configuration to the initial set of patterns
constructed with Self::from_exprs()
.
Implementations§
Source§impl<'a> ExpressionSet<'a>
impl<'a> ExpressionSet<'a>
Sourcepub fn from_exprs(exprs: impl IntoIterator<Item = &'a Expression>) -> Self
pub fn from_exprs(exprs: impl IntoIterator<Item = &'a Expression>) -> Self
Construct a pattern set from references to parsed expressions.
The length of this initial exprs
argument is returned by
Self::len()
, and all subsequent configuration methods are checked to
provide iterators of the same length:
use vectorscan::expression::*;
let a: Expression = "a+".parse().unwrap();
// Fails due to argument length mismatch:
ExpressionSet::from_exprs([&a])
.with_flags([]);
Sourcepub fn with_flags(self, flags: impl IntoIterator<Item = Flags>) -> Self
pub fn with_flags(self, flags: impl IntoIterator<Item = Flags>) -> Self
Provide flags which modify the behavior of each expression.
The length of flags
is checked to be the same as Self::len()
.
If this builder method is not used, Flags::default()
will be assigned
to all patterns.
use vectorscan::{expression::*, flags::*, matchers::*};
// Create two expressions to demonstrate separate flags for each pattern:
let a: Expression = "a+[^a]".parse()?;
let b: Expression = "b+[^b]".parse()?;
// Get the start of match for one pattern, but not the other:
let db = ExpressionSet::from_exprs([&a, &b])
.with_flags([Flags::default(), Flags::SOM_LEFTMOST])
.compile(Mode::BLOCK)?;
let mut scratch = db.allocate_scratch()?;
let mut matches: Vec<&str> = Vec::new();
scratch.scan_sync(&db, "aardvark imbibbe".into(), |m| {
matches.push(unsafe { m.source.as_str() });
MatchResult::Continue
})?;
// Start of match is preserved for only one pattern:
assert_eq!(&matches, &["aar", "aardvar", "bi", "bbe"]);
Sourcepub fn with_ids(self, ids: impl IntoIterator<Item = ExprId>) -> Self
pub fn with_ids(self, ids: impl IntoIterator<Item = ExprId>) -> Self
Assign an ID number to each pattern.
The length of ids
is checked to be the same as Self::len()
. Multiple
patterns can be assigned the same ID.
If this builder method is not used, vectorscan will assign them all the ID number 0:
use vectorscan::{expression::*, flags::*, state::*, matchers::*, sources::*};
// Create two expressions to demonstrate multiple pattern IDs.
let a: Expression = "a+[^a]".parse()?;
let b: Expression = "b+[^b]".parse()?;
// Create one db with ID numbers, and one without.
let set1 = ExpressionSet::from_exprs([&a, &b]).compile(Mode::BLOCK)?;
let set2 = ExpressionSet::from_exprs([&a, &b])
.with_ids([ExprId(300), ExprId(12)])
.compile(Mode::BLOCK)?;
let mut scratch = Scratch::blank();
scratch.setup_for_db(&set1)?;
scratch.setup_for_db(&set2)?;
let msg: ByteSlice = "aardvark imbibbe".into();
// The first db doesn't differentiate matches by ID number:
let mut matches1: Vec<ExpressionIndex> = Vec::new();
scratch.scan_sync(&set1, msg, |m| {
matches1.push(m.id);
MatchResult::Continue
})?;
assert_eq!(
&matches1,
&[ExpressionIndex(0), ExpressionIndex(0), ExpressionIndex(0), ExpressionIndex(0)],
);
// The second db returns corresponding ExpressionIndex instances:
let mut matches2: Vec<ExpressionIndex> = Vec::new();
scratch.scan_sync(&set2, msg, |m| {
matches2.push(m.id);
MatchResult::Continue
})?;
assert_eq!(
&matches2,
&[ExpressionIndex(300), ExpressionIndex(300), ExpressionIndex(12), ExpressionIndex(12)],
);
Sourcepub fn with_exts(
self,
exts: impl IntoIterator<Item = Option<&'a ExprExt>>,
) -> Self
pub fn with_exts( self, exts: impl IntoIterator<Item = Option<&'a ExprExt>>, ) -> Self
Optionally assign ExprExt
configuration to each pattern.
This is the only available entry point to compiling a database with
ExprExt
configuration for a given pattern (i.e. the single
expression compiler does not support extended configuration).
If Expression::ext_info()
succeeds with a given
Expression
/ExprExt
pair, then compiling the same pattern and
configuration into a vectorscan database via an expression set with this
method is likely but not guaranteed to succeed.
use vectorscan::{expression::*, flags::*, matchers::*};
// Apply extended configuration to one version of the pattern, but not the other:
let a: Expression = "a.*b".parse()?;
let a_ext = ExprExt::from_min_length(4);
let set = ExpressionSet::from_exprs([&a, &a])
.with_exts([Some(&a_ext), None])
.with_ids([ExprId(1), ExprId(2)])
.compile(Mode::BLOCK)?;
let mut scratch = set.allocate_scratch()?;
// The configured pattern does not match because of its min length attribute:
let mut matches: Vec<ExpressionIndex> = Vec::new();
scratch.scan_sync(&set, "ab".into(), |m| {
matches.push(m.id);
MatchResult::Continue
})?;
assert_eq!(&matches, &[ExpressionIndex(2)]);
// Howver, both patterns match a longer input:
matches.clear();
scratch.scan_sync(&set, "asssssb".into(), |m| {
matches.push(m.id);
MatchResult::Continue
})?;
assert_eq!(&matches, &[ExpressionIndex(1), ExpressionIndex(2)]);
Sourcepub fn compile(self, mode: Mode) -> Result<Database, VectorscanCompileError>
pub fn compile(self, mode: Mode) -> Result<Database, VectorscanCompileError>
Call Database::compile_multi()
with None
for the platform.
Trait Implementations§
Source§impl<'a> Clone for ExpressionSet<'a>
impl<'a> Clone for ExpressionSet<'a>
Source§fn clone(&self) -> ExpressionSet<'a>
fn clone(&self) -> ExpressionSet<'a>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more