The`regex`crateis[oncrates.io](https://crates.io/crates/regex) and can be usedbyadding`regex`toyourdependenciesinyourproject's`Cargo.toml`. Ormoresimply,justrun`cargoaddregex`.
// We use 'unwrap()' here because it would be a bug in our program if the // pattern failed to compile to a regex. Panicking in the presence of a bug // is okay. letre=Regex::new(r"Homer(.)\.Simpson").unwrap(); lethay="HomerJ.Simpson"; letSome(caps)=re.captures(hay)else{return}; assert_eq!("J",&caps[1]); ```
// Note that (?P<middle>.) is a different way to spell the same thing. letre=Regex::new(r"Homer(?<middle>.)\.Simpson").unwrap(); lethay="HomerJ.Simpson"; letSome(caps)=re.captures(hay)else{return}; assert_eq!("J",&caps["middle"]); ```
letre=Regex::new(r"[0-9]{4}-[0-9]{2}-[0-9]{2}").unwrap(); lethay="Whatdo1865-04-14,1881-07-02,1901-09-06and1963-11-22haveincommon?"; // 'm' is a 'Match', and 'as_str()' returns the matching part of the haystack. letdates:Vec<&str>=re.find_iter(hay).map(|m|m.as_str()).collect(); assert_eq!(dates,vec![ "1865-04-14", "1881-07-02", "1901-09-06", "1963-11-22", ]); ```
letre=Regex::new(r"(?<y>[0-9]{4})-(?<m>[0-9]{2})-(?<d>[0-9]{2})").unwrap(); lethay="Whatdo1865-04-14,1881-07-02,1901-09-06and1963-11-22haveincommon?"; // 'm' is a 'Match', and 'as_str()' returns the matching part of the haystack. letdates:Vec<(&str,&str,&str)>=re.captures_iter(hay).map(|caps|{ // The unwraps are okay because every capture group must match if the whole // regex matches, and in this context, we know we have a match. // // Note that we use `caps.name("y").unwrap().as_str()` instead of // `&caps["y"]` because the lifetime of the former is the same as the // lifetime of `hay` above, but the lifetime of the latter is tied to the // lifetime of `caps` due to how the `Index` trait is defined. letyear=caps.name("y").unwrap().as_str(); letmonth=caps.name("m").unwrap().as_str(); letday=caps.name("d").unwrap().as_str(); (year,month,day) }).collect(); assert_eq!(dates,vec![ ("1865","04","14"), ("1881","07","02"), ("1901","09","06"), ("1963","11","22"), ]); ```
// Iterate over and collect all of the matches. Each match corresponds to the // ID of the matching pattern. letmatches:Vec<_>=set.matches("foobar").into_iter().collect(); assert_eq!(matches,vec![0,2,3,4,6]);
// You can also test whether a particular regex matched: letmatches=set.matches("foobar"); assert!(!matches.matched(5)); assert!(matches.matched(6)); ```
// If we just matches on Greek, then all codepoints would match! letre=Regex::new(r"\p{Greek}+").unwrap(); letsubs:Vec<&str>=re.find_iter("ΔδΔΔδΔ").map(|m|m.as_str()).collect(); assert_eq!(subs,vec!["ΔδΔΔδΔ"]); ```
lethaystack="samwise"; // If 'samwise' comes first in our alternation, then it is // preferred as a match, even if the regex engine could // technically detect that 'sam' led to a match earlier. letre=Regex::new(r"samwise|sam").unwrap(); assert_eq!("samwise",re.find(haystack).unwrap().as_str()); // But if 'sam' comes first, then it will match instead. // In this case, it is impossible for 'samwise' to match // because 'sam' is a prefix of it. letre=Regex::new(r"sam|samwise").unwrap(); assert_eq!("sam",re.find(haystack).unwrap().as_str()); ```
Finally,it'sworthpointingoutthatregexcompilationisguaranteedtotake worstOm proportional size of regex.
ize regex ** the been.
* s)- <java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 59
something small and expand it as[`RegexBuilder::ize_limit`]
to something small and then expand it as needed.
### Untrusted haystacks
The main way this crate guards against searches from taking a long time is by
using algorithms that guarantee a `O(m * n)` worst case time and space bound.
Namely:
* `m` is proportional to the size of the regex, where the size of the regex
includes the expansion of all counted repetitions. (See the previous section on
untrusted patterns.)
* `n` is proportional to the length, in bytes, of the haystack.
In other words, if you consider `m` to be a constant (for example, the regex
pattern is a literal in the source code), then the search can be said to run in"linear time." Or equivalently, "linear time with respect to the size of the
haystack."
But the `m` factor here is important not to ignore. If a regex is
particularly big, the search times can get quite slow. This is why, in part,
[`RegexBuilder::size_limit`] exists.
**Advice for those searching untrusted haystacks**: As long as your regexes
are not enormous, you should expect to be able to search untrusted haystacks
without fear. If you aren't sure, you should benchmark it. Unlike backtracking
engines, if your regex is so big that it's likely to result in slow searches,
this is probably something you'll be able to observe regardless of what the
haystack is made up of.
### Iterating over matches
One thing that is perhaps easy to miss is that the worst case time
complexity bound of `O(m * n)` applies to methods like [`Regex::is_match`],
[`Regex::find`] and [`Regex::captures`]. It does **not** apply to
[`Regex::find_iter`] or [`Regex::captures_iter`]. Namely, since iterating over
all matches can execute many searches, and each search can scan the entire
haystack, the worst case time complexity for iterators is `O(m * n^2)`.
One example of where this occurs is when a pattern consists of an alternation, where an earlier branch of the alternation requires scanning the entire
haystack only to discover that there is no match. It also requires a later
branch of the alternation to have matched at the beginning of the search. For
example, consider the pattern `.*[^A-Z]|[A-Z]` and the haystack `AAAAA`. The
first search will scan to the end looking for matches of `.*[^A-Z]` even though
a finite automata engine (asin this crate) knows that `[A-Z]` has already
matched the first character of the haystack. This is due to the greedy nature
of regex searching. That first search will report a match at the first `A` only
after scanning to the end to discover that no other match exists. The next
search then begins at the second `A` and the behavior repeats.
There is no way to avoid this. This means that if both patterns and haystacks
are untrusted and you're iterating over all matches, you're susceptible to
worst case quadratic time complexity. One possible way to mitigate this
is to drop down to the lower level `regex-automata` crate and use its
`meta::Regex` iterator APIs. There, you can configure the search to operate in"earliest" mode by passing a `Input::new(haystack).earliest(true)` to
`meta::Regex::find_iter` (for example). By enabling this mode, you give up
the normal greedy match semantics of regex searches and instead ask the regex
engine to immediately stop as soon as a match has been found. Enabling this
mode will thus restore the worst case `O(m * n)` time complexity bound, but at
the cost of different semantics.
### Untrusted inputs in practice
While providing a `O(m * n)` worst case time bound on all searches goes a long
way toward preventing [ReDoS], that doesn't mean every search you can possibly
run will complete without burning CPU time. In general, there are a few ways for the `m * n` time bound to still bite you:
* You are searching an exceptionally long haystack. No matter how you slice
it, a longer haystack will take more time to search. This crate may often make
very quick work of even long haystacks because of its literal optimizations,
but those aren't available for all regexes.
* Unicode character classes can cause searches to be quite slow in some cases.
This is especially true when they are combined with counted repetitions. While
the regex size limit above will protect you from the most egregious cases,
the default size limit still permits pretty big regexes that can execute more
slowly than one might expect.
* While routines like [`Regex::find`] and [`Regex::captures`] guarantee
worst case `O(m * n)` search time, routines like [`Regex::find_iter`] and
[`Regex::captures_iter`] actually have worst case `O(m * n^2)` search time.
This is because `find_iter` runs many searches, and each search takes worst
case `O(m * n)` time. Thus, iteration of all matches in a haystack has
worst case `O(m * n^2)`. A good example of a pattern that exhibits this is
`(?:A+){1000}|` or even `.*[^A-Z]|[A-Z]`.
In general, untrusted haystacks are easier to stomach than untrusted patterns.
Untrusted patterns give a lot more control to the caller to impact the
performance of a search. In many cases, a regex search will actually execute in
average case `O(n)` time (i.e., not dependent on the size of the regex), but
this can't be guaranteed in general. Therefore, permitting untrusted patterns
means that your only line of defense is to put a limit on how big `m` (and
perhaps also `n`) can be in `O(m * n)`. `n` is limited by simply inspecting
the length of the haystack while `m` is limited by *both* applying a limit to
the length of the pattern *and* a limit on the compiled size of the regex via
[`RegexBuilder::size_limit`].
It bears repeating: if you're accepting untrusted patterns, it would be a good
idea to start with conservative limits on `m` and `n`, and then carefully
increase them as needed.
# Crate features
By default, this crate tries pretty hard to make regex matching both as fast as possible and as correct as it can be. This means that there is a lot of
code dedicated to performance, the handling of Unicode data and the Unicode
data itself. Overall, this leads to more dependencies, larger binaries and
longer compile times. This trade off may not be appropriate in all cases, and
indeed, even when all Unicode and performance features are disabled, one is
still left with a perfectly serviceable regex engine that will work well in
many cases. (Note that code is not arbitrarily reducible, and for this reason,
the [`regex-lite`](https://docs.rs/regex-lite) crate exists to provide an even
more minimal experience by cutting out Unicode and performance, but still
maintaining the linear search time bound.)
This crate exposes a number of features for controlling that trade off. Some
of these features are strictly performance oriented, such that disabling them
won't result in a loss of functionality, but may result in worse performance.
Other features, such as the ones controlling the presence or absence of Unicode
data, can result in a loss of functionality. For example, if one disables the
`unicode-case` feature (described below), then compiling the regex `(?i)a`
will fail since Unicode case insensitivity is enabled by default. Instead,
callers must use `(?i-u)a` to disable Unicode case folding. Stated differently,
enabling or disabling any of the features below can only add or subtract from
the total set of valid regular expressions. Enabling or disabling a feature
will never modify the match semantics of a regular expression.
Most features below are enabled by default. Features that aren't enabled by
default are noted.
### Ecosystem features
* **std** -
When enabled, this will cause `regex` to use the standard library. In terms
of APIs, `std` causes error types to implement the `std::error::Error` trait. Enabling `std` will also result in performance optimizations,
including SIMD and faster synchronization primitives. Notably, **disabling
the `std` feature will result in the use of spin locks**. To use a regex
engine without `std` and without spin locks, you'll need to drop down to
the [`regex-automata`](https://docs.rs/regex-automata) crate.
* **logging** -
When enabled, the `log` crate is used to emit messages about regex
compilation and search strategies. This is **disabled by default**. This is
typically only useful to someone working on this crate's internals, but might
be useful if you're doing some rabbit hole performance hacking. Or if you're
just interested in the kinds of decisions being made by the regex engine.
### Performance features
**Note**:
To get performance benefits offered by the SIMD, `std` must be enabled.
None of the `perf-*` features will enable `std` implicitly.
* **perf** -
Enables all performance related features except for `perf-dfa-full`. This
feature is enabled by default is intended to cover all reasonable features
that improve performance, even if more are added in the future.
* **perf-dfa** -
Enables the use of a lazy DFA for matching. The lazy DFA is used to compile
portions of a regex to a very fast DFA on an as-needed basis. This can
result in substantial speedups, usually by an order of magnitude on large
haystacks. The lazy DFA does not bring in any new dependencies, but it can
make compile times longer.
* **perf-dfa-full** -
Enables the use of a full DFA for matching. Full DFAs are problematic because
they have worst case `O(2^n)` construction time. For this reason, when this
feature is enabled, full DFAs are only used for very small regexes and a
very small space bound is used during determinization to avoid the DFA
from blowing up. This feature is not enabled by default, even as part of
`perf`, because it results in fairly sizeable increases in binary size and
compilation time. It can result in faster search times, but they tend to be
more modest and limited to non-Unicode regexes.
* **perf-onepass** -
Enables the use of a one-pass DFA for extracting the positions of capture
groups. This optimization applies to a subset of certain types of NFAs and
represents the fastest engine in this cratefor dealing with capture groups.
* **perf-backtrack** -
Enables the use of a bounded backtracking algorithm for extracting the
positions of capture groups. This usually sits between the slowest engine
(the PikeVM) and the fastest engine (one-pass DFA) for extracting capture
groups. It's used whenever the regex is not one-pass and is small enough.
* **perf-inline** -
Enables the use of aggressive inlining inside match routines. This reduces
the overhead of each match. The aggressive inlining, however, increases
compile times and binary size.
* **perf-literal** -
Enables the use of literal optimizations for speeding up matches. In some
cases, literal optimizations can result in speedups of _several_ orders of
magnitude. Disabling this drops the `aho-corasick` and `memchr` dependencies.
* **perf-cache** -
This feature used to enable a faster internal cache at the cost of using
additional dependencies, but this is no longer an option. A fast internal
cache is now used unconditionally with no additional dependencies. This may
change in the future.
### Unicode features
* **unicode** -
Enables all Unicode features. This feature is enabled by default, and will
always cover all Unicode features, even if more are added in the future.
* **unicode-age** -
Provide the data for the
[Unicode `Age` property](https://www.unicode.org/reports/tr44/tr44-24.html#Character_Age).
This makes it possible to use classes like `\p{Age:6.0}` to refer to all
codepoints first introduced in Unicode 6.0
* **unicode-bool** -
Provide the data for numerous Unicode boolean properties. The full list
is not included here, but contains properties like `Alphabetic`, `Emoji`,
`Lowercase`, `Math`, `Uppercase` and `White_Space`.
* **unicode-case** -
Provide the data for case insensitive matching using
[Unicode's "simple loose matches" specification](https://www.unicode.org/reports/tr18/#Simple_Loose_Matches).
* **unicode-gencat** -
Provide the data for
[Unicode general categories](https://www.unicode.org/reports/tr44/tr44-24.html#General_Category_Values).
This includes, but is not limited to, `Decimal_Number`, `Letter`,
`Math_Symbol`, `Number` and `Punctuation`.
* **unicode-perl** -
Provide the data for supporting the Unicode-aware Perl character classes,
corresponding to `\w`, `\s` and `\d`. This is also necessary for using
Unicode-aware word boundary assertions. Note that if this feature is
disabled, the `\s` and `\d` character classes are still available if the
`unicode-bool` and `unicode-gencat` features are enabled, respectively.
* **unicode-script** -
Provide the data for
[Unicode scripts and script extensions](https://www.unicode.org/reports/tr24/).
This includes, but is not limited to, `Arabic`, `Cyrillic`, `Hebrew`,
`Latin` and `Thai`.
* **unicode-segment** -
Provide the data necessary to provide the properties used to implement the
[Unicode text segmentation algorithms](https://www.unicode.org/reports/tr29/).
This enables using classes like `\p{gcb=Extend}`, `\p{wb=Katakana}` and
`\p{sb=ATerm}`.
# Other crates
This crate has two required dependencies and several optional dependencies.
This section briefly describes them with the goal of raising awareness of how
different components of this crate may be used independently.
It is somewhat unusual for a regex engine to have dependencies, as most regex
libraries are self contained units with no dependencies other than a particular
environment's standard library. Indeed, for other similarly optimized regex
engines, most or all of the code in the dependencies of this crate would
normally just be inseparable or coupled parts of the crate itself. But since
Rust and its tooling ecosystem make the use of dependencies so easy, it made
sense to spend some effort de-coupling parts of this crate and making them
independently useful.
We only briefly describe each crate here.
* [`regex-lite`](https://docs.rs/regex-lite) is not a dependency of `regex`,
but rather, a standalone zero-dependency simpler version of `regex` that
prioritizes compile times and binary size. In exchange, it eschews Unicode
support and performance. Its match semantics are as identical as possible to
the `regex` crate, and for the things it supports, its APIs are identical to
the APIs in this crate. In other words, for a lot of use cases, it is a drop-in
replacement.
* [`regex-syntax`](https://docs.rs/regex-syntax) provides a regular expression
parser via `Ast` and `Hir` types. It also provides routines for extracting
literals from a pattern. Folks can use this crate to do analysis, or even to
build their own regex engine without having to worry about writing a parser.
* [`regex-automata`](https://docs.rs/regex-automata) provides the regex engines
themselves. One of the downsides of finite automata based regex engines is that
they often need multiple internal engines in order to have similar or better
performance than an unbounded backtracking engine in practice. `regex-automata` in particular provides public APIs for a PikeVM, a bounded backtracker, a
one-pass DFA, a lazy DFA, a fully compiled DFA and a meta regex engine that
combines all them together. It also has native multi-pattern support and
provides a way to compile and serialize full DFAs such that they can be loaded
and searched in a no-std no-alloc environment. `regex-automata` itself doesn't
even have a required dependency on `regex-syntax`!
* [`memchr`](https://docs.rs/memchr) provides low level SIMD vectorized
routines for quickly finding the location of single bytes or even substrings in a haystack. In other words, it provides fast `memchr` and `memmem` routines.
These are used by this cratein literal optimizations.
* [`aho-corasick`](https://docs.rs/aho-corasick) provides multi-substring
search. It also provides SIMD vectorized routines in the case where the number
of substrings to search for is relatively small. The `regex` crate also uses
this for literal optimizations.
*/
#![no_std] #![deny(missing_docs)] #![cfg_attr(feature = "pattern", feature(pattern))] // This adds Cargo feature annotations to items in the rustdoc output. Which is // sadly hugely beneficial for this crate due to the number of features. #![cfg_attr(docsrs_regex, feature(doc_cfg))] #![warn(missing_debug_implementations)]
mod builders; pubmod bytes; mod error; mod find_byte; #[cfg(feature = "pattern")] mod pattern; mod regex; mod regexset;
/// Escapes all regular expression meta characters in `pattern`. /// /// The string returned may be safely used as a literal in a regular /// expression. pubfn escape(pattern: &str) -> alloc::string::String {
regex_syntax::escape(pattern)
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.87 Sekunden
(vorverarbeitet am 2026-08-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.