1 unstable release
0.1.0 | Aug 3, 2024 |
---|
#768 in Rust patterns
8KB
62 lines
Doc Search DSL (doc_search_dsl)
A Rust procedural macro for creating complex regex patterns using a Domain-Specific Language (DSL). This DSL allows you to define hierarchical regex patterns that can be used with a custom Rule enum for advanced text matching and processing.
Installation
cargo add doc_search_dsl lazy_regex
Usage
Here's a basic example of how to use the DSL:
use doc_search_dsl::{pat, Rule};
fn main() {
let content = vec![
"Once upon a midnight dreary, while I pondered, weak and weary,",
"Over many a quaint and curious volume of forgotten lore—",
"While I nodded, nearly napping, suddenly there came a tapping,",
"As of some one gently rapping, rapping at my chamber door.",
"''Tis some visitor,' I muttered, 'tapping at my chamber door—",
"Only this and nothing more.",
];
let p = pat! {
all {
"nodded",
"WHILE"i,
"nothing"
}
};
assert!(matches!(p, Rule::And(_)));
assert_eq!(p.occurances(&content), 1);
}
This example creates a pattern that matches if all of "nodded", "WHILE" (case-insensitive), and "nothing" are present in the content.
Pattern Types
Let's explore different pattern types, from simple to complex:
1. Single Pattern
The simplest pattern matches a single string:
let p = pat!("dreary");
assert!(matches!(p, Rule::One(_)));
assert_eq!(p.occurances(&content), 1);
This matches any line containing "dreary".
2. Single Pattern with Flags
You can add flags to modify the pattern behavior:
let p = pat!("WHILE"i);
assert!(matches!(p, Rule::One(_)));
assert_eq!(p.occurances(&content), 2);
The i
flag makes the pattern case-insensitive, so it matches both "While" and "while".
3. Any (OR) Pattern
The any
pattern matches if any of its sub-patterns match:
let p = pat! {
any {
"dreary",
"curious",
"tapping"
}
};
assert!(matches!(p, Rule::Or(_)));
assert_eq!(p.occurances(&content), 3);
This matches lines containing "dreary", "curious", or "tapping".
4. All (AND) Pattern
The all
pattern matches if all of its sub-patterns match:
let p = pat! {
all {
"while",
"pondered",
"weary"
}
};
assert!(matches!(p, Rule::And(_)));
assert_eq!(p.occurances(&content), 1);
This matches only if "while", "pondered", and "weary" are all present in the content.
5. Sequence Pattern
The sequence
pattern matches its sub-patterns in order:
let p = pat! {
sequence {
"Once upon",
"midnight",
"dreary"
}
};
assert!(matches!(p, Rule::Sequence(_)));
assert_eq!(p.occurances(&content), 1);
This matches the patterns "Once upon", "midnight", and "dreary" in that specific order.
6. Nested Patterns
You can nest patterns for more complex matching:
let p = pat! {
any {
all {
"dreary",
"weary"
},
sequence {
"tapping",
"rapping"
}
}
};
assert!(matches!(p, Rule::Or(_)));
assert_eq!(p.occurances(&content), 2);
This matches either (both "dreary" and "weary") or ("tapping" followed by "rapping").
7. Complex Pattern
Here's a more complex example combining various pattern types:
let p = pat! {
all {
any {
"dreary",
"curious"
},
sequence {
"while"i,
pat!("I \\w+") // Matches "I" followed by any word
},
pat!(".*more.$") // Matches lines ending with "more."
}
};
assert!(matches!(p, Rule::And(_)));
assert_eq!(p.occurances(&content), 1);
This pattern matches content that:
- Contains either "dreary" or "curious", AND
- Has "while" (case-insensitive) followed by "I" and any word, AND
- Has a line ending with "more."
Conclusion
This DSL provides a flexible and intuitive way to create complex regex patterns in Rust. By combining different pattern types and nesting them, you can create powerful search patterns tailored to your specific needs.
For more detailed information on available methods and advanced usage, please refer to the API documentation.
Dependencies
~3.5–5MB
~96K SLoC