update regex util

This commit is contained in:
Vlasislav Kashin
2025-07-04 18:31:27 +03:00
parent d0fb47705a
commit 29f5e5664c

View File

@@ -1,6 +1,6 @@
use std::borrow::Cow;
use regex::Regex;
use regex::{Captures, Regex};
pub trait RegexFullMatch {
/// Eq of C fullMatch
@@ -10,18 +10,16 @@ pub trait RegexFullMatch {
pub trait RegexConsume {
/// Eq of C Consume
fn consume_start<'a>(&self, s: &'a str) -> Option<Cow<'a, str>> {
self.consume_start_capturing(s, &mut [])
self.consume_start_capturing(s).map(| res| res.0)
}
fn consume_start_capturing<'a, 'b>(&self, s: &'a str, groups: &mut [&'b str]) -> Option<Cow<'a, str>>
where 'a: 'b;
fn consume_start_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)>;
fn find_and_consume<'a>(&self, s: &'a str) -> Option<Cow<'a, str>> {
self.find_and_consume_capturing(s, &mut [])
self.find_and_consume_capturing(s).map(| res| res.0)
}
fn find_and_consume_capturing<'a, 'b>(&self, s: &'a str, groups: &mut [&'b str]) -> Option<Cow<'a, str>>
where 'a: 'b;
fn find_and_consume_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)>;
}
trait RegexMatchStart {
@@ -50,42 +48,24 @@ impl RegexMatchStart for Regex {
}
impl RegexConsume for Regex {
fn consume_start_capturing<'a, 'b>(&self, s: &'a str, groups: &mut [&'b str]) -> Option<Cow<'a, str>>
where 'a: 'b {
_consume(self, s, groups, true)
fn consume_start_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)> {
_consume(self, s, true)
}
fn find_and_consume_capturing<'a, 'b>(&self, s: &'a str, groups: &mut [&'b str]) -> Option<Cow<'a, str>>
where 'a: 'b {
_consume(self, s, groups, false)
fn find_and_consume_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)> {
_consume(self, s, false)
}
}
fn _consume<'a, 'b>(
fn _consume<'a>(
r: &Regex, input: &'a str,
groups: &mut [&'b str], anchor_at_start: bool
) -> Option<Cow<'a, str>>
where 'a: 'b {
anchor_at_start: bool
) -> Option<(Cow<'a, str>, Captures<'a>)> {
let captures = r.captures(input)?;
let full_capture = captures.get(0)?;
if anchor_at_start && full_capture.start() != 0 {
return None
}
// Check if expected groups count is leq
// captures.len includes full group (0), so take captures.len() - 1
if groups.len() > captures.len() - 1 {
return None;
}
// If less matches than expected - fail.
for i in 1..=groups.len() {
// Groups are counted from 1 rather than 0.
if let Some(capture) = captures.get(i) {
groups[i-1] = capture.as_str();
} else {
// should never happen
return None
}
}
Some(Cow::Borrowed(&input[full_capture.end()..]))
Some((Cow::Borrowed(&input[full_capture.end()..]), captures))
}