Struct Captures
struct Captures { ... }
The span offsets of capturing groups after a match has been found.
This type represents the output of regex engines that can report the
offsets at which capturing groups matches or "submatches" occur. For
example, the PikeVM. When a match
occurs, it will at minimum contain the PatternID of the pattern that
matched. Depending upon how it was constructed, it may also contain the
start/end offsets of the entire match of the pattern and the start/end
offsets of each capturing group that participated in the match.
Values of this type are always created for a specific GroupInfo. It is
unspecified behavior to use a Captures value in a search with any regex
engine that has a different GroupInfo than the one the Captures were
created with.
Constructors
There are three constructors for this type that control what kind of information is available upon a match:
- [
Captures::all]: Will store overall pattern match offsets in addition to the offsets of capturing groups that participated in the match. - [
Captures::matches]: Will store only the overall pattern match offsets. The offsets of capturing groups (even ones that participated in the match) are not available. - [
Captures::empty]: Will only store the pattern ID that matched. No match offsets are available at all.
If you aren't sure which to choose, then pick the first one. The first one
is what convenience routines like,
PikeVM::create_captures,
will use automatically.
The main difference between these choices is performance. Namely, if you ask for less information, then the execution of regex search may be able to run more quickly.
Notes
It is worth pointing out that this type is not coupled to any one specific
regex engine. Instead, its coupling is with GroupInfo, which is the
thing that is responsible for mapping capturing groups to "slot" offsets.
Slot offsets are indices into a single sequence of memory at which matching
haystack offsets for the corresponding group are written by regex engines.
Example
This example shows how to parse a simple date and extract the components of the date via capturing groups:
use ;
let re = new?;
let = ;
re.captures;
assert!;
assert_eq!;
assert_eq!;
assert_eq!;
# Ok::
Example: named capturing groups
This example is like the one above, but leverages the ability to name capturing groups in order to make the code a bit clearer:
use ;
let re = new?;
let = ;
re.captures;
assert!;
assert_eq!;
assert_eq!;
assert_eq!;
# Ok::
Implementations
impl Captures
fn all(group_info: GroupInfo) -> CapturesCreate new storage for the offsets of all matching capturing groups.
This routine provides the most information for matches---namely, the spans of matching capturing groups---but also requires the regex search routines to do the most work.
It is unspecified behavior to use the returned
Capturesvalue in a search with aGroupInfoother than the one that is provided to this constructor.Example
This example shows that all capturing groups---but only ones that participated in a match---are available to query after a match has been found:
use ; let re = new?; let mut cache = re.create_cache; let mut caps = all; re.captures; assert!; assert_eq!; // The 'lower' group didn't match, so it won't have any offsets. assert_eq!; assert_eq!; assert_eq!; # Ok::fn matches(group_info: GroupInfo) -> CapturesCreate new storage for only the full match spans of a pattern. This does not include any capturing group offsets.
It is unspecified behavior to use the returned
Capturesvalue in a search with aGroupInfoother than the one that is provided to this constructor.Example
This example shows that only overall match offsets are reported when this constructor is used. Accessing any capturing groups other than the 0th will always return
None.use ; let re = new?; let mut cache = re.create_cache; let mut caps = matches; re.captures; assert!; assert_eq!; // We didn't ask for capturing group offsets, so they aren't available. assert_eq!; assert_eq!; assert_eq!; # Ok::fn empty(group_info: GroupInfo) -> CapturesCreate new storage for only tracking which pattern matched. No offsets are stored at all.
It is unspecified behavior to use the returned
Capturesvalue in a search with aGroupInfoother than the one that is provided to this constructor.Example
This example shows that only the pattern that matched can be accessed from a
Capturesvalue created via this constructor.use ; let re = new_many?; let mut cache = re.create_cache; let mut caps = empty; re.captures; assert!; assert_eq!; // We didn't ask for any offsets, so they aren't available. assert_eq!; re.captures; assert!; assert_eq!; // We didn't ask for any offsets, so they aren't available. assert_eq!; # Ok::fn is_match(self: &Self) -> boolReturns true if and only if this capturing group represents a match.
This is a convenience routine for
caps.pattern().is_some().Example
When using the PikeVM (for example), the lightest weight way of detecting whether a match exists is to create capturing groups that only track the ID of the pattern that match (if any):
use ; let re = new?; let mut cache = re.create_cache; let mut caps = empty; re.captures; assert!; # Ok::fn pattern(self: &Self) -> Option<PatternID>Returns the identifier of the pattern that matched when this capturing group represents a match. If no match was found, then this always returns
None.This returns a pattern ID in precisely the cases in which
is_matchreturnstrue. Similarly, the pattern ID returned is always the same pattern ID found in theMatchreturned byget_match.Example
When using the PikeVM (for example), the lightest weight way of detecting which pattern matched is to create capturing groups that only track the ID of the pattern that match (if any):
use ; let re = new_many?; let mut cache = re.create_cache; let mut caps = empty; re.captures; assert_eq!; // Recall that offsets are only available when using a non-empty // Captures value. So even though a match occurred, this returns None! assert_eq!; # Ok::fn get_match(self: &Self) -> Option<Match>Returns the pattern ID and the span of the match, if one occurred.
This always returns
NonewhenCaptureswas created withCaptures::empty, even if a match was found.If this routine returns a non-
Nonevalue, thenis_matchis guaranteed to returntrueandpatternis also guaranteed to return a non-Nonevalue.Example
This example shows how to get the full match from a search:
use ; let re = new_many?; let = ; re.captures; assert_eq!; # Ok::fn get_group(self: &Self, index: usize) -> Option<Span>Returns the span of a capturing group match corresponding to the group index given, only if both the overall pattern matched and the capturing group participated in that match.
This returns
Noneifindexis invalid.indexis valid if and only if it's less thanCaptures::group_lenfor the matching pattern.This always returns
NonewhenCaptureswas created withCaptures::empty, even if a match was found. This also always returnsNonefor anyindex > 0whenCaptureswas created withCaptures::matches.If this routine returns a non-
Nonevalue, thenis_matchis guaranteed to returntrue,patternis guaranteed to return a non-Nonevalue andget_matchis guaranteed to return a non-Nonevalue.By convention, the 0th capture group will always return the same span as the span returned by
get_match. This is because the 0th capture group always corresponds to the entirety of the pattern's match. (It is similarly always unnamed because it is implicit.) This isn't necessarily true of all regex engines. For example, one can hand-compile athompson::NFAvia athompson::Builder, which isn't technically forced to make the 0th capturing group always correspond to the entire match.Example
This example shows how to get the capturing groups, by index, from a match:
# if cfg! // miri takes too long use ; let re = new?; let = ; re.captures; assert_eq!; assert_eq!; assert_eq!; // Looking for a non-existent capturing group will return None: assert_eq!; # // literals are too big for 32-bit usize: #1039 # assert_eq!; # Ok::fn get_group_by_name(self: &Self, name: &str) -> Option<Span>Returns the span of a capturing group match corresponding to the group name given, only if both the overall pattern matched and the capturing group participated in that match.
This returns
Noneifnamedoes not correspond to a valid capturing group for the pattern that matched.This always returns
NonewhenCaptureswas created withCaptures::empty, even if a match was found. This also always returnsNonefor anyindex > 0whenCaptureswas created withCaptures::matches.If this routine returns a non-
Nonevalue, thenis_matchis guaranteed to returntrue,patternis guaranteed to return a non-Nonevalue andget_matchis guaranteed to return a non-Nonevalue.Example
This example shows how to get the capturing groups, by name, from a match:
# if cfg! // miri takes too long use ; let re = new?; let = ; re.captures; assert_eq!; assert_eq!; assert_eq!; // Looking for a non-existent capturing group will return None: assert_eq!; # Ok::fn iter(self: &Self) -> CapturesPatternIter<'_>Returns an iterator of possible spans for every capturing group in the matching pattern.
If this
Capturesvalue does not correspond to a match, then the iterator returned yields no elements.Note that the iterator returned yields elements of type
Option<Span>. A span is present if and only if it corresponds to a capturing group that participated in a match.Example
This example shows how to collect all capturing groups:
# if cfg! // miri takes too long use ; let re = new?; let = ; re.captures; assert!; let groups: = caps.iter.collect; assert_eq!; # Ok::This example uses the same regex as the previous example, but with a haystack that omits the middle name. This results in a capturing group that is present in the elements yielded by the iterator but without a match:
# if cfg! // miri takes too long use ; let re = new?; let = ; re.captures; assert!; let groups: = caps.iter.collect; assert_eq!; # Ok::fn group_len(self: &Self) -> usizeReturn the total number of capturing groups for the matching pattern.
If this
Capturesvalue does not correspond to a match, then this always returns0.This always returns the same number of elements yielded by
Captures::iter. That is, the number includes capturing groups even if they don't participate in the match.Example
This example shows how to count the total number of capturing groups associated with a pattern. Notice that it includes groups that did not participate in a match (just like
Captures::iterdoes).# if cfg! // miri takes too long use PikeVM; let re = new?; let = ; re.captures; assert_eq!; # Ok::fn group_info(self: &Self) -> &GroupInfoReturns a reference to the underlying group info on which these captures are based.
The difference between
GroupInfoandCapturesis that the former defines the structure of capturing groups where as the latter is what stores the actual match information. So where asCapturesonly gives you access to the current match,GroupInfolets you query any information about all capturing groups, even ones for patterns that weren't involved in a match.Note that a
GroupInfouses reference counting internally, so it may be cloned cheaply.Example
This example shows how to get all capturing group names from the underlying
GroupInfo. Notice that we don't even need to run a search.use ; let re = new_many?; let caps = re.create_captures; let expected = vec!; // We could also just use 're.get_nfa().group_info()'. let got: = caps.group_info.all_names.collect; assert_eq!; # Ok::fn interpolate_string(self: &Self, haystack: &str, replacement: &str) -> StringInterpolates the capture references in
replacementwith the corresponding substrings inhaystackmatched by each reference. The interpolated string is returned.See the
interpolatemodule for documentation on the format of the replacement string.Example
This example shows how to use interpolation, and also shows how it can work with multi-pattern regexes.
use ; let re = new_many?; let mut cache = re.create_cache; let mut caps = re.create_captures; let replacement = "year=$year, month=$month, day=$day"; // This matches the first pattern. let hay = "On 14-03-2010, I became a Tenneessee lamb."; re.captures; let result = caps.interpolate_string; assert_eq!; // And this matches the second pattern. let hay = "On 2010-03-14, I became a Tenneessee lamb."; re.captures; let result = caps.interpolate_string; assert_eq!; # Ok::fn interpolate_string_into(self: &Self, haystack: &str, replacement: &str, dst: &mut String)Interpolates the capture references in
replacementwith the corresponding substrings inhaystackmatched by each reference. The interpolated string is written todst.See the
interpolatemodule for documentation on the format of the replacement string.Example
This example shows how to use interpolation, and also shows how it can work with multi-pattern regexes.
use ; let re = new_many?; let mut cache = re.create_cache; let mut caps = re.create_captures; let replacement = "year=$year, month=$month, day=$day"; // This matches the first pattern. let hay = "On 14-03-2010, I became a Tenneessee lamb."; re.captures; let mut dst = Stringnew; caps.interpolate_string_into; assert_eq!; // And this matches the second pattern. let hay = "On 2010-03-14, I became a Tenneessee lamb."; re.captures; let mut dst = Stringnew; caps.interpolate_string_into; assert_eq!; # Ok::fn interpolate_bytes(self: &Self, haystack: &[u8], replacement: &[u8]) -> Vec<u8>Interpolates the capture references in
replacementwith the corresponding substrings inhaystackmatched by each reference. The interpolated byte string is returned.See the
interpolatemodule for documentation on the format of the replacement string.Example
This example shows how to use interpolation, and also shows how it can work with multi-pattern regexes.
use ; let re = new_many?; let mut cache = re.create_cache; let mut caps = re.create_captures; let replacement = b"year=$year, month=$month, day=$day"; // This matches the first pattern. let hay = b"On 14-03-2010, I became a Tenneessee lamb."; re.captures; let result = caps.interpolate_bytes; assert_eq!; // And this matches the second pattern. let hay = b"On 2010-03-14, I became a Tenneessee lamb."; re.captures; let result = caps.interpolate_bytes; assert_eq!; # Ok::fn interpolate_bytes_into(self: &Self, haystack: &[u8], replacement: &[u8], dst: &mut Vec<u8>)Interpolates the capture references in
replacementwith the corresponding substrings inhaystackmatched by each reference. The interpolated byte string is written todst.See the
interpolatemodule for documentation on the format of the replacement string.Example
This example shows how to use interpolation, and also shows how it can work with multi-pattern regexes.
use ; let re = new_many?; let mut cache = re.create_cache; let mut caps = re.create_captures; let replacement = b"year=$year, month=$month, day=$day"; // This matches the first pattern. let hay = b"On 14-03-2010, I became a Tenneessee lamb."; re.captures; let mut dst = vec!; caps.interpolate_bytes_into; assert_eq!; // And this matches the second pattern. let hay = b"On 2010-03-14, I became a Tenneessee lamb."; re.captures; let mut dst = vec!; caps.interpolate_bytes_into; assert_eq!; # Ok::fn extract<'h, N: usize>(self: &Self, haystack: &'h str) -> (&'h str, [&'h str; N])This is a convenience routine for extracting the substrings corresponding to matching capture groups in the given
haystack. Thehaystackshould be the same substring used to find the match spans in thisCapturesvalue.This is identical to
Captures::extract_bytes, except it works with&strinstead of&[u8].Panics
This panics if the number of explicit matching groups in this
Capturesvalue is less thanN. This also panics if thisCapturesvalue does not correspond to a match.Note that this does not panic if the number of explicit matching groups is bigger than
N. In that case, only the firstNmatching groups are extracted.Example
use PikeVM; let re = new?; let mut cache = re.create_cache; let mut caps = re.create_captures; let hay = "On 2010-03-14, I became a Tenneessee lamb."; re.captures; assert!; let = caps.extract; assert_eq!; assert_eq!; assert_eq!; assert_eq!; // We can also ask for fewer than all capture groups. let = caps.extract; assert_eq!; assert_eq!; # Ok::fn extract_bytes<'h, N: usize>(self: &Self, haystack: &'h [u8]) -> (&'h [u8], [&'h [u8]; N])This is a convenience routine for extracting the substrings corresponding to matching capture groups in the given
haystack. Thehaystackshould be the same substring used to find the match spans in thisCapturesvalue.This is identical to
Captures::extract, except it works with&[u8]instead of&str.Panics
This panics if the number of explicit matching groups in this
Capturesvalue is less thanN. This also panics if thisCapturesvalue does not correspond to a match.Note that this does not panic if the number of explicit matching groups is bigger than
N. In that case, only the firstNmatching groups are extracted.Example
use PikeVM; let re = new?; let mut cache = re.create_cache; let mut caps = re.create_captures; let hay = b"On 2010-03-14, I became a Tenneessee lamb."; re.captures; assert!; let = caps.extract_bytes; assert_eq!; assert_eq!; assert_eq!; assert_eq!; // We can also ask for fewer than all capture groups. let = caps.extract_bytes; assert_eq!; assert_eq!; # Ok::
impl Captures
fn clear(self: &mut Self)Clear this
Capturesvalue.After clearing, all slots inside this
Capturesvalue will be set toNone. Similarly, any pattern ID that it was previously associated with (for a match) is erased.It is not usually necessary to call this routine. Namely, a
Capturesvalue only provides high level access to the capturing groups of the pattern that matched, and only low level access to individual slots. Thus, even if slots corresponding to groups that aren't associated with the matching pattern are set, then it won't impact the higher level APIs. Namely, higher level APIs likeCaptures::get_groupwill returnNoneif no pattern ID is present, even if there are spans set in the underlying slots.Thus, to "clear" a
Capturesvalue of a match, it is usually only necessary to callCaptures::set_patternwithNone.Example
This example shows what happens when a
Capturesvalue is cleared.# if cfg! // miri takes too long use PikeVM; let re = new?; let = ; re.captures; assert!; let slots: = caps.slots.iter.map.collect; // Note that the following ordering is considered an API guarantee. assert_eq!; // Now clear the slots. Everything is gone and it is no longer a match. caps.clear; assert!; let slots: = caps.slots.iter.map.collect; assert_eq!; # Ok::fn set_pattern(self: &mut Self, pid: Option<PatternID>)Set the pattern on this
Capturesvalue.When the pattern ID is
None, then thisCapturesvalue does not correspond to a match (is_matchwill returnfalse). Otherwise, it corresponds to a match.This is useful in search implementations where you might want to initially call
set_pattern(None)in order to avoid the cost of callingclear()if it turns out to not be necessary.Example
This example shows that
set_patternmerely overwrites the pattern ID. It does not actually change the underlying slot values.# if cfg! // miri takes too long use PikeVM; let re = new?; let = ; re.captures; assert!; assert!; let slots: = caps.slots.iter.map.collect; // Note that the following ordering is considered an API guarantee. assert_eq!; // Now set the pattern to None. Note that the slot values remain. caps.set_pattern; assert!; assert!; let slots: = caps.slots.iter.map.collect; // Note that the following ordering is considered an API guarantee. assert_eq!; # Ok::fn slots(self: &Self) -> &[Option<NonMaxUsize>]Returns the underlying slots, where each slot stores a single offset.
Every matching capturing group generally corresponds to two slots: one slot for the starting position and another for the ending position. Typically, either both are present or neither are. (The weasel word "typically" is used here because it really depends on the regex engine implementation. Every sensible regex engine likely adheres to this invariant, and every regex engine in this crate is sensible.)
Generally speaking, callers should prefer to use higher level routines like
Captures::get_matchorCaptures::get_group.An important note here is that a regex engine may not reset all of the slots to
Nonevalues when no match occurs, or even when a match of a different pattern occurs. But this depends on how the regex engine implementation deals with slots.Example
This example shows how to get the underlying slots from a regex match.
use ; let re = new_many?; let = ; re.captures; assert_eq!; // Note that the only guarantee we have here is that slots 2 and 3 // are set to correct values. The contents of the first two slots are // unspecified since the 0th pattern did not match. let expected = &; assert_eq!; # Ok::fn slots_mut(self: &mut Self) -> &mut [Option<NonMaxUsize>]Returns the underlying slots as a mutable slice, where each slot stores a single offset.
This tends to be most useful for regex engine implementations for writing offsets for matching capturing groups to slots.
See
Captures::slotsfor more information about slots.
impl Clone for Captures
fn clone(self: &Self) -> Captures
impl Debug for Captures
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl Freeze for Captures
impl RefUnwindSafe for Captures
impl Send for Captures
impl Sync for Captures
impl Unpin for Captures
impl UnsafeUnpin for Captures
impl UnwindSafe for Captures
impl<T> Any for Captures
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for Captures
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for Captures
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for Captures
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> From for Captures
fn from(t: T) -> TReturns the argument unchanged.
impl<T> ToOwned for Captures
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T, U> Into for Captures
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for Captures
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for Captures
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>