Skip to content

Commit

Permalink
Add regex.matchPos
Browse files Browse the repository at this point in the history
A convenience function, which does the slicing and position adjustments
for you, to match at a given position within the haystack string.
  • Loading branch information
mnemnion committed Aug 6, 2024
1 parent 676d76d commit 641ef3f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The provided Regex type allows 64 'operations' and 8 unique ASCII character sets
Drop the file into your project, or use the Zig build system:

```zig
zig fetch --save "https://github.com/mnemnion/mvzr/archive/refs/tags/v0.1.2.tar.gz"
zig fetch --save "https://github.com/mnemnion/mvzr/archive/refs/tags/v0.2.0.tar.gz"
```

I'll do my best to keep that URL fresh, but it pays to check over here: ➔
Expand Down
3 changes: 3 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ pub fn build(b: *std.Build) void {
// set a preferred release mode, allowing the user to decide how to optimize.
const optimize = b.standardOptimizeOption(.{});

const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};

// Creates a step for unit testing. This only builds the test executable
// but does not run it.
const lib_unit_tests = b.addTest(.{
.root_source_file = b.path("src/mvzr.zig"),
.target = target,
.optimize = optimize,
.filters = test_filters,
});

const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
Expand Down
28 changes: 28 additions & 0 deletions src/mvzr.zig
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,25 @@ pub fn SizedRegex(ops: comptime_int, char_sets: comptime_int) type {
}
}

/// Match a regex pattern in `haystack` after `pos`. Returns a `Match`
/// if the pattern is found.
pub fn matchPos(regex: *const SizedRegexT, pos: usize, haystack: []const u8) ?Match {
const substack = haystack[pos..];
if (substack.len == 0) return null;
const maybe_matched = regex.matchInternal(substack);
if (maybe_matched) |m| {
const m1 = pos + m[0];
const m2 = pos + m[1];
return Match{
.slice = haystack[m1..m2],
.start = m1,
.end = m2,
};
} else {
return null;
}
}

/// Boolean test if the regex matches in the haystack.
pub fn isMatch(regex: *const SizedRegexT, haystack: []const u8) bool {
const maybe_matched = regex.matchInternal(haystack);
Expand Down Expand Up @@ -2119,6 +2138,7 @@ test "workshop" {
// printRegexString("^[a-zA-Z0-9_!#$%&.-]+@([a-zA-Z0-9.-])+$");
// try testMatchAll("^[a-zA-Z0-9_!#$%&.-]+@([a-zA-Z0-9.-])+$", "[email protected]");
//
try testMatchAll("(a[bc]){3,5}ac", "abacabacac");
}

test "heap allocated regex and match" {
Expand Down Expand Up @@ -2167,6 +2187,14 @@ test "iteration" {
try expectEqual(null, r_iter.next());
}

test "matchPos" {
const regex = Regex.compile("abcd").?;
const matched = regex.matchPos(4, "abcdabcd").?;
try expectEqual(4, matched.start);
try expectEqualStrings("abcd", matched.slice);
try expectEqual(8, matched.end);
}

test "comptime regex" {
const comp_regex = comptime compile("foo+").?;
const run_match = comp_regex.match("foofoofoo");
Expand Down

0 comments on commit 641ef3f

Please sign in to comment.