### Zig Zig Build System Installation
Source: https://github.com/mnemnion/mvzr/blob/trunk/README.md
Shows how to add the mvzr library to a Zig project using the `zig fetch` command to download a specific version of the library archive.
```zig
zig fetch --save "https://github.com/mnemnion/mvzr/archive/refs/tags/v0.3.7.tar.gz"
```
--------------------------------
### Zig Regex Compilation and Matching Example
Source: https://github.com/mnemnion/mvzr/blob/trunk/README.md
Demonstrates how to compile a regex pattern string and perform matching against a haystack string using the mvzr library. It shows basic usage of `compile`, `match`, `isMatch`, and `iterator` methods, as well as runtime ownership handling.
```zig
const regex: mvzr.Regex = mvzr.compile(patt_str).?;
// or mvzr.Regex.compile(patt_str)
const match: mvzr.Match = regex.match(haystack).?;
const match2: mvzr.Match = match(haystack, patt_str).?;
const did_match: bool = regex.isMatch(haystack);
const iter: mvzr.RegexIterator = regex.iterator(haystack);
while (iter.next()) |m| {
// ...
}
// Comptime-only
const ops, const sets = mvzr.resourcesNeeded("abc?d*[^efgh]++2");
// I suggest adding the values directly here once they're established
const SlimmedDownRegex = mvzr.SizedRegex(ops, sets);
```
--------------------------------
### Match Regex at Specific Position in Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
This example demonstrates how to find a regex pattern starting at a particular offset within a string. The `matchPos` function is used to locate the next match after a given position. The returned match positions are relative to the original string. It requires the mvzr library.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
const log_line = "2024-01-15 ERROR: Failed at 2024-01-15 10:30:45";
const date_regex = mvzr.compile("[0-9]{4}-[0-9]{2}-[0-9]{2}").?;
// Find first date
if (date_regex.match(log_line)) |first| {
std.debug.print("First date: {s} at {}\n", .{first.slice, first.start});
// Find second date starting after first match
if (date_regex.matchPos(first.end, log_line)) |second| {
std.debug.print("Second date: {s} at {}\n", .{second.slice, second.start});
// Output:
// First date: 2024-01-15 at 0
// Second date: 2024-01-15 at 27
}
}
}
```
--------------------------------
### Understanding Quantifiers (Greedy, Lazy, Possessive) in Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
Illustrates the behavior of greedy, lazy, and possessive quantifiers (*, +, ?, {m,n}) in regular expressions using the mvzr library. Covers matching as much as possible, as little as possible, and without backtracking, with examples for HTML tag matching.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
const text = "aaaaaab";
// Greedy quantifiers: *, +, ?, {m,n}
const greedy = mvzr.compile("a*ab").?;
if (greedy.match(text)) |m| {
std.debug.print("Greedy 'a*ab': '{s}'\n", .{m.slice});
// Matches: 'aaaaaab' - takes all 'a's then backtracks to match 'ab'
}
// Lazy quantifiers: *?, +?, ??, {m,n}?
const lazy = mvzr.compile("a*?ab").?;
if (lazy.match(text)) |m| {
std.debug.print("Lazy 'a*?ab': '{s}'\n", .{m.slice});
// Matches: 'ab' - takes minimal 'a's to match pattern
}
// Possessive quantifiers: *+, ++, ?+
const possessive = mvzr.compile("a*+ab").?;
const poss_match = possessive.match(text);
std.debug.print("Possessive 'a*+ab': {}\n", .{poss_match == null});
// No match: 'a*+' greedily takes all 'a's and won't backtrack
// Practical examples
const html = "
content
";
const greedy_tag = mvzr.compile("<.*>").?;
if (greedy_tag.match(html)) |m| {
std.debug.print("Greedy tag: '{s}'\n", .{m.slice});
// Matches: 'content
' - full string
}
const lazy_tag = mvzr.compile("<.*?>").?;
if (lazy_tag.match(html)) |m| {
std.debug.print("Lazy tag: '{s}'\n", .{m.slice});
// Matches: '' - stops at first '>'
}
// Repetition counts
const patterns = [_][]const u8{
"a{3}", // exactly 3
"a{2,5}", // 2 to 5
"a{3,}", // 3 or more
"a{,4}", // up to 4
"a{2,4}?", // 2 to 4, lazy
"a{3,5}+", // 3 to 5, possessive
};
for (patterns) |patt| {
const rx = mvzr.compile(patt).?;
if (rx.match(text)) |m| {
std.debug.print("'{s}' matched '{s}'\n", .{patt, m.slice});
}
}
}
```
--------------------------------
### Determine Regex Resource Requirements in Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
This example shows how to use the `mvzr.resourcesNeeded` comptime function to analyze regex patterns and determine the number of operations and character sets required. This information is crucial for creating optimally sized `SizedRegex` types for improved performance and memory usage. It depends on the mvzr library.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
// Define patterns at comptime
const email_pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
const url_pattern = "^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/[^\\s]*)?$";
// Calculate resources at comptime
const email_ops, const email_sets = mvzr.resourcesNeeded(email_pattern);
const url_ops, const url_sets = mvzr.resourcesNeeded(url_pattern);
// Create optimized types
const EmailRegex = mvzr.SizedRegex(email_ops, email_sets);
const UrlRegex = mvzr.SizedRegex(url_ops, url_sets);
pub fn main() !void {
std.debug.print("Email regex: {} ops, {} sets\n", .{email_ops, email_sets});
std.debug.print("URL regex: {} ops, {} sets\n", .{url_ops, url_sets});
const email_rx = EmailRegex.compile(email_pattern).?;
const url_rx = UrlRegex.compile(url_pattern).?;
std.debug.print("Valid email: {}\n", .{email_rx.isMatch("user@example.com")});
std.debug.print("Valid URL: {}\n", .{url_rx.isMatch("https://example.com/path")});
}
```
--------------------------------
### Using Character Classes and Escape Sequences in Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
Demonstrates the use of built-in character classes (e.g., \d, \w, \s) and escape sequences (e.g., \n, \t, \xXX) for pattern matching with the mvzr library. It also shows custom character sets and boundary anchors. Operates on ASCII characters only.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
const test_cases = [_]struct { []const u8, []const u8, bool }{
// Character classes
.{ "\\d+", "12345", true }, // \d = digits [0-9]
.{ "\\D+", "abc", true }, // \D = non-digits
.{ "\\w+", "hello_world123", true }, // \w = word chars [A-Za-z0-9_]
.{ "\\W+", "!@#$", true }, // \W = non-word chars
.{ "\\s+", " \t\n", true }, // \s = whitespace
.{ "\\S+", "text", true }, // \S = non-whitespace
// Escape sequences
.{ "line1\\nline2", "line1\nline2", true }, // \n = newline
.{ "col1\\ttab2", "col1\tcol2", true }, // \t = tab
.{ "data\\r\\n", "data\r\n", true }, // \r = carriage return
.{ "\\x48\\x65\\x6c\\x6c\\x6f", "Hello", true }, // \xXX = hex byte
// Custom character sets
.{ "[a-z]+", "hello", true },
.{ "[^0-9]+", "text", true },
.{ "[A-Za-z0-9._%+-]+", "user_name.123", true },
// Boundary anchors
.{ "^start", "start of line", true },
.{ "end$", "line end", true },
.{ "\\bword\\b", "a word here", true }, // \b = word boundary
.{ "\\Bin\\B", "string", true }, // \B = not word boundary
};
for (test_cases) |tc| {
const regex = mvzr.compile(tc[0]).?;
const result = regex.isMatch(tc[1]);
std.debug.print("Pattern '{s}' on '{s}': {}\n", .{tc[0], tc[1], result});
if (result != tc[2]) {
std.debug.print(" UNEXPECTED: expected {}\n", .{tc[2]});
}
}
}
```
--------------------------------
### Allocate Regex on Heap - Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
Copies a stack-allocated regex to the heap, returning a pointer. This is useful when compiled regexes need to persist beyond the current scope. It utilizes `mvzr.compile` and `toOwnedRegex` for heap allocation.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
const RegexCache = struct {
common_patterns: std.StringHashMap(*const mvzr.Regex),
allocator: std.mem.Allocator,
pub fn init(allocator: std.mem.Allocator) !RegexCache {
var cache = RegexCache{
.common_patterns = std.StringHashMap(*const mvzr.Regex).init(allocator),
.allocator = allocator,
};
// Pre-compile and cache common patterns
const patterns = [_]struct { []const u8, []const u8 } {
.{ "email", "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}" },
.{ "phone", "[0-9]{3}-[0-9]{3}-[0-9]{4}" },
.{ "ip", "([0-9]{1,3}\\.){3}[0-9]{1,3}" },
};
for (patterns) |p| {
const regex = mvzr.compile(p[1]).?;
const heap_regex = try regex.toOwnedRegex(allocator);
try cache.common_patterns.put(p[0], heap_regex);
}
return cache;
}
pub fn deinit(self: *RegexCache) void {
var it = self.common_patterns.valueIterator();
while (it.next()) |regex_ptr| {
self.allocator.destroy(regex_ptr.*);
}
self.common_patterns.deinit();
}
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var cache = try RegexCache.init(gpa.allocator());
defer cache.deinit();
const email_regex = cache.common_patterns.get("email").?;
std.debug.print("Match: {}\n", .{email_regex.isMatch("test@example.com")});
}
```
--------------------------------
### Create Custom-Sized Regex Type in Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
This code snippet illustrates how to create a regex type with custom operation and character set limits using `mvzr.SizedRegex`. The `resourcesNeeded` function helps determine the optimal sizes for specific patterns, leading to memory efficiency. It requires the mvzr library.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
// Analyze pattern complexity
const pattern = "(0[1-9]|1[012])[\\/](0[1-9]|[12][0-9]|3[01])[\\/][0-9]{4}";
const ops, const sets = mvzr.resourcesNeeded(pattern);
std.debug.print("Pattern needs {} ops and {} character sets\n", .{ops, sets});
// Create optimized regex type
const DateRegex = mvzr.SizedRegex(ops, sets);
const date_regex = DateRegex.compile(pattern).?;
// Use the specialized type
const test_dates = [_][]const u8{
"12/31/2024", // valid
"02/29/2024", // valid
"13/01/2024", // invalid month
};
for (test_dates) |date| {
const valid = date_regex.isMatch(date);
std.debug.print("{s}: {}\n", .{date, valid});
}
}
```
--------------------------------
### Compile Zig Regex Pattern at Compile-time and Runtime
Source: https://context7.com/mnemnion/mvzr/llms.txt
Compiles a regex pattern string into a Regex struct, supporting both compile-time and runtime compilation. Returns null if the pattern is invalid. This function is essential for preparing regex patterns for matching operations.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
// Runtime compilation
const pattern = "\\w+@[\\w.-]+\\.[a-z]{2,}";
const regex = mvzr.compile(pattern) orelse {
std.log.err("Failed to compile pattern", .{});
return error.InvalidPattern;
};
// Compile-time compilation (validated at compile time)
const comptime_regex = comptime mvzr.compile("[0-9]{3}-[0-9]{4}").?;
// Check both patterns
const email_match = regex.match("user@example.com");
const phone_match = comptime_regex.match("555-1234");
std.debug.print("Email matched: {s}\\n", .{!email_match == null});
std.debug.print("Phone matched: {s}\\n", .{!phone_match == null});
}
```
--------------------------------
### Copy Match to Owned Memory - Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
Creates a copy of a `Match` with its own allocated memory for the slice. This ensures that the extracted match data persists independently of the original haystack's lifetime. It uses `mvzr.Match.toOwnedMatch` for this purpose.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
const ExtractedData = struct {
matches: std.ArrayList(mvzr.Match),
allocator: std.mem.Allocator,
pub fn init(allocator: std.mem.Allocator) ExtractedData {
return .{ .matches = std.ArrayList(mvzr.Match).init(allocator), .allocator = allocator };
}
pub fn deinit(self: *ExtractedData) void {
for (self.matches.items) |m| {
m.deinit(self.allocator);
}
self.matches.deinit();
}
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var data = ExtractedData.init(allocator);
defer data.deinit();
// Extract data from a temporary buffer
{
var buffer: [256]u8 = undefined;
const text = try std.fmt.bufPrint(&buffer, "IDs: {s}, {s}, {s}", .{1234, 5678, 9012});
const regex = mvzr.compile("[0-9]+").?;
var iter = regex.iterator(text);
while (iter.next()) |m| {
const owned = try m.toOwnedMatch(allocator);
try data.matches.append(owned);
}
} // buffer goes out of scope
// Matches still valid after buffer is gone
std.debug.print("Extracted {d} IDs:\n", .{data.matches.items.len});
for (data.matches.items) |m| {
std.debug.print(" {s}\n", .{m.slice});
}
}
```
--------------------------------
### Test Zig Regex Pattern Match in String
Source: https://context7.com/mnemnion/mvzr/llms.txt
Provides a boolean test to determine if a pattern exists within a string. It is more efficient than the `match()` function when only the presence of a match is required, not the details of the match itself.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn validateInput(input: []const u8) !bool {
const validators = .{
.{ "email", "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" },
.{ "phone", "^[0-9]{3}-[0-9]{3}-[0-9]{4}$" },
.{ "zipcode", "^[0-9]{5}(-[0-9]{4})?$" },
};
inline for (validators) |validator| {
const regex = mvzr.compile(validator[1]).?;
if (regex.isMatch(input)) {
std.debug.print("Valid {s}: {s}\\n", .{validator[0], input});
return true;
}
}
std.debug.print("Input does not match any format\\n", .{});
return false;
}
pub fn main() !void {
_ = try validateInput("user@example.com"); // Valid email
_ = try validateInput("555-123-4567"); // Valid phone
_ = try validateInput("invalid"); // No match
}
```
--------------------------------
### Quick Zig Regex Match Without Explicit Compilation
Source: https://context7.com/mnemnion/mvzr/llms.txt
A convenience function that compiles a regex pattern and performs a match in a single operation. This is ideal for one-off pattern checks where reusing the compiled regex is not necessary, simplifying the matching process.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
const haystack = "The year is 2024";
const pattern = "[0-9]{4}";
if (mvzr.match(haystack, pattern)) |m| {
std.debug.print("Found year: {s}\\n", .{m.slice});
}
// Multiple quick matches
const patterns = [_][]const u8{ "\\d+", "[A-Z]\\w+", "is" };
for (patterns) |patt| {
if (mvzr.match(haystack, patt)) |m| {
std.debug.print("Pattern '{s}' matched: '{s}'\\n", .{patt, m.slice});
}
}
}
```
--------------------------------
### Iterate Over All Regex Matches in Zig
Source: https://context7.com/mnemnion/mvzr/llms.txt
This snippet shows how to use an iterator to find all non-overlapping matches of a regex pattern within a given string. It returns an iterator that yields each match or null when exhausted. Dependencies include the standard Zig library and the mvzr library.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
const text = "Contact: alice@example.com or bob@test.org for info";
const email_pattern = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}";
const regex = mvzr.compile(email_pattern).?;
var iter = regex.iterator(text);
var count: usize = 0;
std.debug.print("Found emails:\n", .{});
while (iter.next()) |m| {
count += 1;
std.debug.print(" {}: '{s}' at {}..{}\n", .{count, m.slice, m.start, m.end});
}
// Output:
// Found emails:
// 1: 'alice@example.com' at 9..26
// 2: 'bob@test.org' at 30..42
std.debug.print("Total matches: {}\n", .{count});
}
```
--------------------------------
### Match Zig Regex Pattern in String
Source: https://context7.com/mnemnion/mvzr/llms.txt
Searches for the first occurrence of a compiled regex pattern within a given string (haystack). Returns a Match struct detailing the matched slice and its position, or null if no match is found. This is useful for extracting substrings that conform to a pattern.
```zig
const std = @import("std");
const mvzr = @import("mvzr");
pub fn main() !void {
const regex = mvzr.compile("foo+bar").?;
const haystack = "prefix fooooobar suffix";
if (regex.match(haystack)) |m| {
std.debug.print("Match found: '{s}'\\n", .{m.slice});
std.debug.print("Position: {d}..{d}\\n", .{m.start, m.end});
std.debug.print("Full text: '{s}'\\n", .{haystack[m.start..m.end]});
} else {
std.debug.print("No match found\\n", .{});
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.