mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-regexp: add README.md
document supported syntax, Ruby API, engine architecture, limitations, configuration, and license. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
# mruby-regexp
|
||||
|
||||
Built-in regular expression engine for mruby using a Pike VM (NFA
|
||||
simulation) with backtracking fallback.
|
||||
|
||||
## Features
|
||||
|
||||
### Pattern Syntax
|
||||
|
||||
- `.` any character (except newline by default)
|
||||
- `*`, `+`, `?` greedy quantifiers
|
||||
- `*?`, `+?`, `??` non-greedy quantifiers
|
||||
- `{n}`, `{n,}`, `{n,m}` repetition counts
|
||||
- `[abc]`, `[a-z]`, `[^abc]` character classes
|
||||
- `\d`, `\w`, `\s` digit, word, whitespace shortcuts
|
||||
- `\D`, `\W`, `\S` negated shortcuts
|
||||
- `(...)` capture group
|
||||
- `(?:...)` non-capturing group
|
||||
- `(?<name>...)` named capture group
|
||||
- `|` alternation
|
||||
- `\1`-`\9` backreferences
|
||||
- `(?=...)` positive lookahead
|
||||
- `(?!...)` negative lookahead
|
||||
|
||||
### Anchors
|
||||
|
||||
- `^` beginning of line
|
||||
- `$` end of line
|
||||
- `\A` beginning of string
|
||||
- `\z` end of string
|
||||
- `\Z` end of string (or before final newline)
|
||||
- `\b` word boundary
|
||||
- `\B` non-word boundary
|
||||
|
||||
### Flags
|
||||
|
||||
- `i` (`Regexp::IGNORECASE`) case-insensitive matching (ASCII)
|
||||
- `m` (`Regexp::MULTILINE`) `.` matches newline; `^`/`$` match at line boundaries
|
||||
|
||||
### Ruby API
|
||||
|
||||
```ruby
|
||||
# Regexp
|
||||
re = Regexp.new("pattern", Regexp::IGNORECASE)
|
||||
re = /pattern/i # literal syntax
|
||||
re.match("string") # => MatchData or nil
|
||||
re.match?("string") # => true/false
|
||||
re =~ "string" # => index or nil
|
||||
re === "string" # => true/false (for case/when)
|
||||
re.source # => "pattern"
|
||||
re.options # => flags integer
|
||||
Regexp.escape("a.b") # => "a\\.b"
|
||||
Regexp.last_match(n) # => nth capture from last match
|
||||
|
||||
# MatchData
|
||||
md = /(\w+)@(\w+)/.match("user@host")
|
||||
md[0] # => "user@host" (full match)
|
||||
md[1] # => "user"
|
||||
md[2] # => "host"
|
||||
md[:name] # named capture access
|
||||
md.captures # => ["user", "host"]
|
||||
md.to_a # => ["user@host", "user", "host"]
|
||||
md.begin(0) # => match start position
|
||||
md.end(0) # => match end position
|
||||
md.pre_match # => string before match
|
||||
md.post_match # => string after match
|
||||
md.named_captures # => {"name" => "value", ...}
|
||||
|
||||
# String methods
|
||||
str.match(re) # => MatchData or nil
|
||||
str.match?(re) # => true/false
|
||||
str =~ re # => index or nil
|
||||
str.sub(re, replacement) # replace first occurrence
|
||||
str.sub(re) { |m| ... } # replace with block
|
||||
str.gsub(re, replacement) # replace all occurrences
|
||||
str.gsub(re) { |m| ... } # replace all with block
|
||||
str.scan(re) # => array of matches
|
||||
str.split(re) # => array of parts
|
||||
|
||||
# Global variables
|
||||
$~ # last MatchData
|
||||
```
|
||||
|
||||
## Engine Architecture
|
||||
|
||||
The gem uses two execution engines:
|
||||
|
||||
**Pike VM (NFA simulation)**: Used for patterns without
|
||||
backreferences, non-greedy quantifiers, or lookahead. Guarantees
|
||||
O(pattern x text) time complexity, making it immune to ReDoS
|
||||
attacks.
|
||||
|
||||
**Backtracking engine**: Used when patterns contain `\1`-`\9`
|
||||
backreferences, non-greedy quantifiers (`*?`, `+?`, `??`), or
|
||||
lookahead assertions (`(?=...)`, `(?!...)`). Protected by a
|
||||
configurable step limit (`MRB_REGEXP_STEP_LIMIT`, default 1M) to
|
||||
prevent excessive backtracking.
|
||||
|
||||
The engine is selected automatically at compile time based on
|
||||
pattern analysis.
|
||||
|
||||
## Limitations
|
||||
|
||||
- **No lookbehind**: `(?<=...)` and `(?<!...)` are not supported.
|
||||
- **No Unicode properties**: `\p{Alpha}`, `\p{L}`, etc. are not
|
||||
supported.
|
||||
- **No extended mode**: The `x` flag (free-spacing mode) is not
|
||||
supported.
|
||||
- **ASCII case folding only**: The `i` flag handles ASCII letters
|
||||
only.
|
||||
- **Step limit on backtracking**: Patterns that require the
|
||||
backtracking engine are subject to a step limit.
|
||||
|
||||
## Configuration
|
||||
|
||||
```c
|
||||
/* Maximum step count for backtracking engine (ReDoS protection) */
|
||||
#ifndef MRB_REGEXP_STEP_LIMIT
|
||||
#define MRB_REGEXP_STEP_LIMIT 1000000
|
||||
#endif
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT License. See the mruby license file for details.
|
||||
|
||||
This gem is an original implementation. No external regexp library
|
||||
code is used.
|
||||
Reference in New Issue
Block a user