Struct fancy_regex::Regex
source · pub struct Regex { /* private fields */ }
Expand description
A compiled regular expression.
Implementations§
source§impl Regex
impl Regex
sourcepub fn new(re: &str) -> Result<Regex>
pub fn new(re: &str) -> Result<Regex>
Parse and compile a regex with default options, see RegexBuilder
.
Returns an Error
if the pattern could not be parsed.
sourcepub fn is_match(&self, text: &str) -> Result<bool>
pub fn is_match(&self, text: &str) -> Result<bool>
Check if the regex matches the input text.
Example
Test if some text contains the same word twice:
let re = Regex::new(r"(\w+) \1").unwrap();
assert!(re.is_match("mirror mirror on the wall").unwrap());
sourcepub fn find_iter<'r, 't>(&'r self, text: &'t str) -> Matches<'r, 't> ⓘ
pub fn find_iter<'r, 't>(&'r self, text: &'t str) -> Matches<'r, 't> ⓘ
Returns an iterator for each successive non-overlapping match in text
.
If you have capturing groups in your regex that you want to extract, use the Regex::captures_iter() method.
Example
Find all words followed by an exclamation point:
let re = Regex::new(r"\w+(?=!)").unwrap();
let mut matches = re.find_iter("so fancy! even with! iterators!");
assert_eq!(matches.next().unwrap().unwrap().as_str(), "fancy");
assert_eq!(matches.next().unwrap().unwrap().as_str(), "with");
assert_eq!(matches.next().unwrap().unwrap().as_str(), "iterators");
assert!(matches.next().is_none());
sourcepub fn find<'t>(&self, text: &'t str) -> Result<Option<Match<'t>>>
pub fn find<'t>(&self, text: &'t str) -> Result<Option<Match<'t>>>
Find the first match in the input text.
If you have capturing groups in your regex that you want to extract, use the Regex::captures() method.
Example
Find a word that is followed by an exclamation point:
let re = Regex::new(r"\w+(?=!)").unwrap();
assert_eq!(re.find("so fancy!").unwrap().unwrap().as_str(), "fancy");
sourcepub fn find_from_pos<'t>(
&self,
text: &'t str,
pos: usize
) -> Result<Option<Match<'t>>>
pub fn find_from_pos<'t>( &self, text: &'t str, pos: usize ) -> Result<Option<Match<'t>>>
Returns the first match in text
, starting from the specified byte position pos
.
Examples
Finding match starting at a position:
let re = Regex::new(r"(?m:^)(\d+)").unwrap();
let text = "1 test 123\n2 foo";
let mat = re.find_from_pos(text, 7).unwrap().unwrap();
assert_eq!(mat.start(), 11);
assert_eq!(mat.end(), 12);
Note that in some cases this is not the same as using the find
method and passing a slice of the string, see Regex::captures_from_pos() for details.
sourcepub fn captures_iter<'r, 't>(&'r self, text: &'t str) -> CaptureMatches<'r, 't> ⓘ
pub fn captures_iter<'r, 't>(&'r self, text: &'t str) -> CaptureMatches<'r, 't> ⓘ
Returns an iterator over all the non-overlapping capture groups matched in text
.
Examples
Finding all matches and capturing parts of each:
let re = Regex::new(r"(\d{4})-(\d{2})").unwrap();
let text = "It was between 2018-04 and 2020-01";
let mut all_captures = re.captures_iter(text);
let first = all_captures.next().unwrap().unwrap();
assert_eq!(first.get(1).unwrap().as_str(), "2018");
assert_eq!(first.get(2).unwrap().as_str(), "04");
assert_eq!(first.get(0).unwrap().as_str(), "2018-04");
let second = all_captures.next().unwrap().unwrap();
assert_eq!(second.get(1).unwrap().as_str(), "2020");
assert_eq!(second.get(2).unwrap().as_str(), "01");
assert_eq!(second.get(0).unwrap().as_str(), "2020-01");
assert!(all_captures.next().is_none());
sourcepub fn captures<'t>(&self, text: &'t str) -> Result<Option<Captures<'t>>>
pub fn captures<'t>(&self, text: &'t str) -> Result<Option<Captures<'t>>>
Returns the capture groups for the first match in text
.
If no match is found, then Ok(None)
is returned.
Examples
Finding matches and capturing parts of the match:
let re = Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();
let text = "The date was 2018-04-07";
let captures = re.captures(text).unwrap().unwrap();
assert_eq!(captures.get(1).unwrap().as_str(), "2018");
assert_eq!(captures.get(2).unwrap().as_str(), "04");
assert_eq!(captures.get(3).unwrap().as_str(), "07");
assert_eq!(captures.get(0).unwrap().as_str(), "2018-04-07");
sourcepub fn captures_from_pos<'t>(
&self,
text: &'t str,
pos: usize
) -> Result<Option<Captures<'t>>>
pub fn captures_from_pos<'t>( &self, text: &'t str, pos: usize ) -> Result<Option<Captures<'t>>>
Returns the capture groups for the first match in text
, starting from
the specified byte position pos
.
Examples
Finding captures starting at a position:
let re = Regex::new(r"(?m:^)(\d+)").unwrap();
let text = "1 test 123\n2 foo";
let captures = re.captures_from_pos(text, 7).unwrap().unwrap();
let group = captures.get(1).unwrap();
assert_eq!(group.as_str(), "2");
assert_eq!(group.start(), 11);
assert_eq!(group.end(), 12);
Note that in some cases this is not the same as using the captures
method and passing a slice of the string, see the capture that we get
when we do this:
let re = Regex::new(r"(?m:^)(\d+)").unwrap();
let text = "1 test 123\n2 foo";
let captures = re.captures(&text[7..]).unwrap().unwrap();
assert_eq!(captures.get(1).unwrap().as_str(), "123");
This matched the number “123” because it’s at the beginning of the text of the string slice.
sourcepub fn captures_len(&self) -> usize
pub fn captures_len(&self) -> usize
Returns the number of captures, including the implicit capture of the entire expression.
sourcepub fn capture_names(&self) -> CaptureNames<'_> ⓘ
pub fn capture_names(&self) -> CaptureNames<'_> ⓘ
Returns an iterator over the capture names.
sourcepub fn replace<'t, R: Replacer>(&self, text: &'t str, rep: R) -> Cow<'t, str>
pub fn replace<'t, R: Replacer>(&self, text: &'t str, rep: R) -> Cow<'t, str>
Replaces the leftmost-first match with the replacement provided.
The replacement can be a regular string (where $N
and $name
are
expanded to match capture groups) or a function that takes the matches’
Captures
and returns the replaced string.
If no match is found, then a copy of the string is returned unchanged.
Replacement string syntax
All instances of $name
in the replacement text is replaced with the
corresponding capture group name
.
name
may be an integer corresponding to the index of the
capture group (counted by order of opening parenthesis where 0
is the
entire match) or it can be a name (consisting of letters, digits or
underscores) corresponding to a named capture group.
If name
isn’t a valid capture group (whether the name doesn’t exist
or isn’t a valid index), then it is replaced with the empty string.
The longest possible name is used. e.g., $1a
looks up the capture
group named 1a
and not the capture group at index 1
. To exert more
precise control over the name, use braces, e.g., ${1}a
.
To write a literal $
use $$
.
Examples
Note that this function is polymorphic with respect to the replacement. In typical usage, this can just be a normal string:
let re = Regex::new("[^01]+").unwrap();
assert_eq!(re.replace("1078910", ""), "1010");
But anything satisfying the Replacer
trait will work. For example,
a closure of type |&Captures| -> String
provides direct access to the
captures corresponding to a match. This allows one to access
capturing group matches easily:
let re = Regex::new(r"([^,\s]+),\s+(\S+)").unwrap();
let result = re.replace("Springsteen, Bruce", |caps: &Captures| {
format!("{} {}", &caps[2], &caps[1])
});
assert_eq!(result, "Bruce Springsteen");
But this is a bit cumbersome to use all the time. Instead, a simple
syntax is supported that expands $name
into the corresponding capture
group. Here’s the last example, but using this expansion technique
with named capture groups:
let re = Regex::new(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)").unwrap();
let result = re.replace("Springsteen, Bruce", "$first $last");
assert_eq!(result, "Bruce Springsteen");
Note that using $2
instead of $first
or $1
instead of $last
would produce the same result. To write a literal $
use $$
.
Sometimes the replacement string requires use of curly braces to delineate a capture group replacement and surrounding literal text. For example, if we wanted to join two words together with an underscore:
let re = Regex::new(r"(?P<first>\w+)\s+(?P<second>\w+)").unwrap();
let result = re.replace("deep fried", "${first}_$second");
assert_eq!(result, "deep_fried");
Without the curly braces, the capture group name first_
would be
used, and since it doesn’t exist, it would be replaced with the empty
string.
Finally, sometimes you just want to replace a literal string with no
regard for capturing group expansion. This can be done by wrapping a
byte string with NoExpand
:
use fancy_regex::NoExpand;
let re = Regex::new(r"(?P<last>[^,\s]+),\s+(\S+)").unwrap();
let result = re.replace("Springsteen, Bruce", NoExpand("$2 $last"));
assert_eq!(result, "$2 $last");
sourcepub fn replace_all<'t, R: Replacer>(
&self,
text: &'t str,
rep: R
) -> Cow<'t, str>
pub fn replace_all<'t, R: Replacer>( &self, text: &'t str, rep: R ) -> Cow<'t, str>
Replaces all non-overlapping matches in text
with the replacement
provided. This is the same as calling replacen
with limit
set to
0
.
See the documentation for replace
for details on how to access
capturing group matches in the replacement string.
sourcepub fn replacen<'t, R: Replacer>(
&self,
text: &'t str,
limit: usize,
rep: R
) -> Cow<'t, str>
pub fn replacen<'t, R: Replacer>( &self, text: &'t str, limit: usize, rep: R ) -> Cow<'t, str>
Replaces at most limit
non-overlapping matches in text
with the
replacement provided. If limit
is 0, then all non-overlapping matches
are replaced.
Will panic if any errors are encountered. Use try_replacen
, which this
function unwraps, if you want to handle errors.
See the documentation for replace
for details on how to access
capturing group matches in the replacement string.
sourcepub fn try_replacen<'t, R: Replacer>(
&self,
text: &'t str,
limit: usize,
rep: R
) -> Result<Cow<'t, str>>
pub fn try_replacen<'t, R: Replacer>( &self, text: &'t str, limit: usize, rep: R ) -> Result<Cow<'t, str>>
Replaces at most limit
non-overlapping matches in text
with the
replacement provided. If limit
is 0, then all non-overlapping matches
are replaced.
Propagates any errors encountered, such as RuntimeError::BacktrackLimitExceeded
.
See the documentation for replace
for details on how to access
capturing group matches in the replacement string.