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 std::borrow::Cow;
use regex::Regex; use regex::{Captures, Regex};
pub trait RegexFullMatch { pub trait RegexFullMatch {
/// Eq of C fullMatch /// Eq of C fullMatch
@@ -10,18 +10,16 @@ pub trait RegexFullMatch {
pub trait RegexConsume { pub trait RegexConsume {
/// Eq of C Consume /// Eq of C Consume
fn consume_start<'a>(&self, s: &'a str) -> Option<Cow<'a, str>> { 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>> fn consume_start_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)>;
where 'a: 'b;
fn find_and_consume<'a>(&self, s: &'a str) -> Option<Cow<'a, str>> { 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>> fn find_and_consume_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)>;
where 'a: 'b;
} }
trait RegexMatchStart { trait RegexMatchStart {
@@ -50,42 +48,24 @@ impl RegexMatchStart for Regex {
} }
impl RegexConsume for Regex { impl RegexConsume for Regex {
fn consume_start_capturing<'a, 'b>(&self, s: &'a str, groups: &mut [&'b str]) -> Option<Cow<'a, str>> fn consume_start_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)> {
where 'a: 'b { _consume(self, s, true)
_consume(self, s, groups, true)
} }
fn find_and_consume_capturing<'a, 'b>(&self, s: &'a str, groups: &mut [&'b str]) -> Option<Cow<'a, str>> fn find_and_consume_capturing<'a>(&self, s: &'a str) -> Option<(Cow<'a, str>, Captures<'a>)> {
where 'a: 'b { _consume(self, s, false)
_consume(self, s, groups, false)
} }
} }
fn _consume<'a, 'b>( fn _consume<'a>(
r: &Regex, input: &'a str, r: &Regex, input: &'a str,
groups: &mut [&'b str], anchor_at_start: bool anchor_at_start: bool
) -> Option<Cow<'a, str>> ) -> Option<(Cow<'a, str>, Captures<'a>)> {
where 'a: 'b {
let captures = r.captures(input)?; let captures = r.captures(input)?;
let full_capture = captures.get(0)?; let full_capture = captures.get(0)?;
if anchor_at_start && full_capture.start() != 0 { if anchor_at_start && full_capture.start() != 0 {
return None 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. Some((Cow::Borrowed(&input[full_capture.end()..]), captures))
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()..]))
} }