
# tecs.regex


Compiled regular expressions over Lua byte strings.

Patterns use the Rust `regex` crate's syntax. Compilation builds the
automaton once; every method on the returned
[`Regex`](/modules/regex/#tecs.regex.Regex) reuses it. Inline flags
such as `(?i)` and `(?m)` configure a pattern without a second options
vocabulary.

```teal
local trailingDigits <const> = tecs.regex.compile([[(\d+)$]])

local frame <const> = trailingDigits:find("sprites/hero_04")
if frame ~= nil then
    print(frame.value, frame.first, frame.last)
end

print(trailingDigits:replaceAll("hero_04 orc_11", "N"))
```

Subjects remain byte strings, including strings that are not valid UTF-8.
Match positions therefore follow Lua's string functions: 1-based,
inclusive byte indices. An empty match has `last == first - 1`.

## Module contents

### Types

| Type | Kind | Description |
| --- | --- | --- |
| [`Captures`](/modules/regex/#tecs.regex.Captures) | <span class="tealdoc-kind-badge tealdoc-kind-record">record</span> | Contains a whole match and its populated capture groups. |
| [`Match`](/modules/regex/#tecs.regex.Match) | <span class="tealdoc-kind-badge tealdoc-kind-record">record</span> | Describes one matched byte range. |
| [`Regex`](/modules/regex/#tecs.regex.Regex) | <span class="tealdoc-kind-badge tealdoc-kind-record">record</span> | Represents a compiled Rust regular expression. |

### Functions

| Function | Kind | Description |
| --- | --- | --- |
| [`compile`](/modules/regex/#tecs.regex.compile) | <span class="tealdoc-kind-badge tealdoc-kind-static">Static</span> | Compiles a Rust regular expression. |

## Types

<a id="tecs.regex.Captures"></a>
### tecs.regex.Captures <span class="tealdoc-kind-badge tealdoc-kind-record">record</span>

Contains a whole match and its populated capture groups.


```teal
record tecs.regex.Captures
    whole: Match
    groups: {Match}
    groupCount: integer
    named: {string: Match}
end
```

<a id="tecs.regex.Captures.whole"></a>
#### tecs.regex.Captures.whole <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains group zero, which covers the whole match.


```teal
tecs.regex.Captures.whole: Match
```

<a id="tecs.regex.Captures.groups"></a>
#### tecs.regex.Captures.groups <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains explicit groups by their 1-based index. An
unmatched optional group leaves a hole.


```teal
tecs.regex.Captures.groups: {Match}
```

<a id="tecs.regex.Captures.groupCount"></a>
#### tecs.regex.Captures.groupCount <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Reports the number of explicit groups in the pattern,
including groups that did not match.


```teal
tecs.regex.Captures.groupCount: integer
```

<a id="tecs.regex.Captures.named"></a>
#### tecs.regex.Captures.named <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Maps matched group names to the same values in `groups`.


```teal
tecs.regex.Captures.named: {string: Match}
```

<a id="tecs.regex.Match"></a>
### tecs.regex.Match <span class="tealdoc-kind-badge tealdoc-kind-record">record</span>

Describes one matched byte range.


```teal
record tecs.regex.Match
    value: string
    first: integer
    last: integer
    index: integer
    name: string
end
```

<a id="tecs.regex.Match.value"></a>
#### tecs.regex.Match.value <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains the bytes copied from the matched range.


```teal
tecs.regex.Match.value: string
```

<a id="tecs.regex.Match.first"></a>
#### tecs.regex.Match.first <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Reports the first matched byte using a 1-based index.


```teal
tecs.regex.Match.first: integer
```

<a id="tecs.regex.Match.last"></a>
#### tecs.regex.Match.last <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Reports the inclusive last matched byte. An empty match
reports `first - 1`.


```teal
tecs.regex.Match.last: integer
```

<a id="tecs.regex.Match.index"></a>
#### tecs.regex.Match.index <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Reports the capture-group index, with zero for the whole
match.


```teal
tecs.regex.Match.index: integer
```

<a id="tecs.regex.Match.name"></a>
#### tecs.regex.Match.name <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains the capture name, or nil for an unnamed group.


```teal
tecs.regex.Match.name: string
```

<a id="tecs.regex.Regex"></a>
### tecs.regex.Regex <span class="tealdoc-kind-badge tealdoc-kind-record">record</span>

Represents a compiled Rust regular expression.


```teal
record tecs.regex.Regex
    pattern: string

    captures: function(self, subject: string, init: integer): Captures
    find: function(self, subject: string, init: integer): Match
    isMatch: function(self, subject: string): boolean
    replace: function(
        self, subject: string, replacement: string
    ): string
    replaceAll: function(
        self, subject: string, replacement: string
    ): string
end
```

<a id="tecs.regex.Regex.pattern"></a>
#### tecs.regex.Regex.pattern <span class="tealdoc-kind-badge tealdoc-kind-field">field</span>

Read-only. Contains the source pattern unchanged.


```teal
tecs.regex.Regex.pattern: string
```

<a id="tecs.regex.Regex.captures"></a>
#### tecs.regex.Regex:captures <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Finds the first match and every capture group it populated.

`groups` may contain holes when optional groups do not participate;
iterate through `groupCount`, not `#groups`. A named entry aliases
the same [`Match`](/modules/regex/#tecs.regex.Match) stored at its numbered index.



```teal
function tecs.regex.Regex.captures(
    self, subject: string, init: integer
): Captures
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Regex` |  |
| `subject` | `string` | Arbitrary bytes. |
| `init` | `integer` | First byte considered, under the same rules as `find`. |

##### Returns

| Type | Description |
| --- | --- |
| [`Captures`](/modules/regex/#tecs.regex.Captures) | The whole match, numbered groups and named aliases, or nil when nothing matches. |

<a id="tecs.regex.Regex.find"></a>
#### tecs.regex.Regex:find <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Finds the first match at or after a byte position.



```teal
function tecs.regex.Regex.find(
    self, subject: string, init: integer
): Match
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Regex` |  |
| `subject` | `string` | Arbitrary bytes. |
| `init` | `integer` | First byte considered, under `string.find`'s rules: 1 by default, a negative value counts back from the end, and the method clamps a value before 1 to 1. |

##### Returns

| Type | Description |
| --- | --- |
| [`Match`](/modules/regex/#tecs.regex.Match) | The matched bytes and their range, or nil when nothing matches. |

#### Examples

```teal
local regex <const> = require("tecs.regex").compile([[\d+]])
local found <const> = assert(regex:find("hp=100"))

assert(found.value == "100")
```

<a id="tecs.regex.Regex.isMatch"></a>
#### tecs.regex.Regex:isMatch <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Reports whether any part of a subject matches.



```teal
function tecs.regex.Regex.isMatch(self, subject: string): boolean
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Regex` |  |
| `subject` | `string` | Arbitrary bytes. Unlike the pattern, these need not be UTF-8. |

##### Returns

| Type | Description |
| --- | --- |
| `boolean` | True when the expression matches at least once. |

#### Examples

```teal
local regex <const> = require("tecs.regex").compile([[\.(png|jpg)$]])

assert(regex:isMatch("sprite.png"))
```

<a id="tecs.regex.Regex.replace"></a>
#### tecs.regex.Regex:replace <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Replaces the first match.

The method expands capture references in the replacement: `$0` is the whole match, `$1` is the
first group, `$name` and `${name}` select a named group, and `$$` writes one dollar
sign. A reference the pattern does not declare expands to an empty string.



```teal
function tecs.regex.Regex.replace(
    self, subject: string, replacement: string
): string
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Regex` |  |
| `subject` | `string` | Arbitrary bytes. |
| `replacement` | `string` | Arbitrary bytes, with capture references interpreted as described above. |

##### Returns

| Type | Description |
| --- | --- |
| `string` | A new string when something matched, or the original string unchanged when nothing did. |

#### Examples

```teal
local regex <const> = require("tecs.regex").compile([[(\w+)=(\d+)]])

assert(regex:replace("hp=100 mp=50", "$1: $2") == "hp: 100 mp=50")
```

<a id="tecs.regex.Regex.replaceAll"></a>
#### tecs.regex.Regex:replaceAll <span class="tealdoc-kind-badge tealdoc-kind-instance">Instance</span>

Replaces every non-overlapping match.



```teal
function tecs.regex.Regex.replaceAll(
    self, subject: string, replacement: string
): string
```

##### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `self` | `Regex` |  |
| `subject` | `string` | Arbitrary bytes. |
| `replacement` | `string` | The same capture-reference syntax as `replace`. |

##### Returns

| Type | Description |
| --- | --- |
| `string` | A new string when something matched, or the original string unchanged when nothing did. |

#### Examples

```teal
local regex <const> = require("tecs.regex").compile([[\d+]])

assert(regex:replaceAll("room 12, floor 3", "#") == "room #, floor #")
```

## Functions

<a id="tecs.regex.compile"></a>
### tecs.regex.compile <span class="tealdoc-kind-badge tealdoc-kind-static">Static</span>

Compiles a Rust regular expression.

Compilation raises on malformed syntax or a pattern that is not UTF-8.
Rust's Unicode character classes work by default; use inline
flags to change the expression, such as `(?i)` for case-insensitive
matching or `(?-u:.)` for one arbitrary byte.

Keep the returned object and reuse it. The Lua collector releases its
native allocation automatically.



```teal
function tecs.regex.compile(pattern: string): Regex
```

#### Arguments

| Name | Type | Description |
| --- | --- | --- |
| `pattern` | `string` | Rust regex syntax, with NUL bytes allowed where that syntax allows them. |

#### Returns

| Type | Description |
| --- | --- |
| [`Regex`](/modules/regex/#tecs.regex.Regex) | A compiled expression whose native allocation the Lua collector releases. |