# Regular Expressions Built-ins

Regular expressions are an important tool for defining and testing patterns, making them useful in a range of policy use cases. Regular expressions enable specifying and enforcing rules on text data, such as validating input formats or extracting relevant substrings for further processing.

Rego's regular expression functions use the RE2[1](#user-content-fn-1) standard, known for its safety and performance features. RE2 avoids slow performance in common cases making it good for use in performance sensitive environments like policy evaluation.

Here is a simple rule based on a regular expression:

```
email_valid := regex.match(`^[^@]+@[^@]+\.[^@]+$`, "name@example.com")
```

In this example, the `email_valid` will be true as the email matches the pattern. Also note that the pattern is defined as a raw string, which is a common practice as it avoids the need to escape special characters[2](#user-content-fn-2).

While regular expressions are useful in many policies, it's important to consider performance and readability. For simple string operations, such as checking for a substring or performing exact matches, Rego's built-in string matching functions can be faster and easier to read by non-developers.

tip

Check out [regex101.com](https://regex101.com/r/ygG2RR/1) and use the RE2 syntax to test your Rego patterns in a visual way.

| Function | Description | Meta |
| --- | --- | --- |
| `regex.find_all_string_submatch_n` | `output := regex.find_all_string_submatch_n(pattern, value, number)`  Returns all successive matches of the expression.  **Arguments:**  `pattern` (string)  regular expression  `value` (string)  string to match  `number` (number)  number of matches to return; `-1` means all matches  **Returns:**  `output` (array\[array\[string\]\])  array of all matches | Wasm |
| `regex.find_n` | `output := regex.find_n(pattern, value, number)`  Returns the specified number of matches when matching the input against the pattern.  **Arguments:**  `pattern` (string)  regular expression  `value` (string)  string to match  `number` (number)  number of matches to return, if `-1`, returns all matches  **Returns:**  `output` (array\[string\])  collected matches | SDK-dependent |
| `regex.globs_match` | `result := regex.globs_match(glob1, glob2)`  Checks if the intersection of two glob-style regular expressions matches a non-empty set of non-empty strings. The set of regex symbols is limited for this builtin: only `.`, `*`, `+`, `[`, `-`, `]` and `\` are treated as special symbols.  **Arguments:**  `glob1` (string)  first glob-style regular expression  `glob2` (string)  second glob-style regular expression  **Returns:**  `result` (boolean)  true if the intersection of `glob1` and `glob2` matches a non-empty set of non-empty strings | SDK-dependent |
| `regex.is_valid` | `result := regex.is_valid(pattern)`  Checks if a string is a valid regular expression: the detailed syntax for patterns is defined by https://github.com/google/re2/wiki/Syntax.  **Arguments:**  `pattern` (string)  regular expression  **Returns:**  `result` (boolean)  true if `pattern` is a valid regular expression | [v0.23.0](https://github.com/open-policy-agent/opa/releases/v0.23.0) Wasm |
| `regex.match` | `result := regex.match(pattern, value)`  Matches a string against a regular expression.  **Arguments:**  `pattern` (string)  regular expression  `value` (string)  value to match against `pattern`  **Returns:**  `result` (boolean)  true if `value` matches `pattern` | [v0.23.0](https://github.com/open-policy-agent/opa/releases/v0.23.0) Wasm |
| `regex.replace` | `output := regex.replace(s, pattern, value)`  Find and replaces the text using the regular expression pattern.  **Arguments:**  `s` (string)  string being processed  `pattern` (string)  regex pattern to be applied  `value` (string)  regex value  **Returns:**  `output` (string)  string with replaced substrings | [v0.45.0](https://github.com/open-policy-agent/opa/releases/v0.45.0) SDK-dependent |
| `regex.split` | `output := regex.split(pattern, value)`  Splits the input string by the occurrences of the given pattern.  **Arguments:**  `pattern` (string)  regular expression  `value` (string)  string to match  **Returns:**  `output` (array\[string\])  the parts obtained by splitting `value` | SDK-dependent |
| `regex.template_match` | `result := regex.template_match(template, value, delimiter_start, delimiter_end)`  Matches a string against a pattern, where there pattern may be glob-like  **Arguments:**  `template` (string)  template expression containing `0..n` regular expressions  `value` (string)  string to match  `delimiter_start` (string)  start delimiter of the regular expression in `template`  `delimiter_end` (string)  end delimiter of the regular expression in `template`  **Returns:**  `result` (boolean)  true if `value` matches the `template` | SDK-dependent |

## Examples

### `match`

`regex.match()` is a commonly used built-in function that checks if a string matches a given regular expression pattern. The function returns `true` if the string matches the pattern and `false` otherwise.

Some examples of policy use cases where `regex.match()` might be used include:

*   Validating formats, such as ensuring an email address follows a specific pattern or checking if a credit card number matches common formats.
*   Matching HTTP paths to specific patterns for routing or access control purposes.

tip

Check out [regex101.com](https://regex101.com/r/ygG2RR/1) and use the RE2 syntax to test your Rego patterns in a visual way.

Pattern email validation

Validating emails with Regular Expressions is a common policy task. Email validation is more complicated than just checking an email matches a pattern, but since a Rego policy is often a first point of contact, doing a pattern based test on emails is still a good idea as it can help surface issues to users early if they make a mistake.

`regex.match` is the best way to validate emails in Rego.

policy.rego

```
package playimport rego.v1example_email_1 := "foo [at] example.com"example_email_2 := "foo@example.com"match_1 := regex.match(`^[^@]+@[^@]+\.[^@]+$`, example_email_1)match_2 := regex.match(`^[^@]+@[^@]+\.[^@]+$`, example_email_2)match_3 := regex.match(`^[^@]+@[^@]+\.[^@]+$`, input.email)
```

Output

{
  "example\_email\_1": "foo \[at\] example.com",
  "example\_email\_2": "foo@example.com",
  "match\_1": false,
  "match\_2": true,
  "match\_3": false
}

input.json

```
{  "email": "hello at example.com"}
```

data.json

```
{}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcImVtYWlsXCI6IFwiaGVsbG8gYXQgZXhhbXBsZS5jb21cIlxufSIsImQiOiJ7fSIsInAiOiJwYWNrYWdlIHBsYXlcblxuaW1wb3J0IHJlZ28udjFcblxuZXhhbXBsZV9lbWFpbF8xIDo9IFwiZm9vIFthdF0gZXhhbXBsZS5jb21cIlxuXG5leGFtcGxlX2VtYWlsXzIgOj0gXCJmb29AZXhhbXBsZS5jb21cIlxuXG5tYXRjaF8xIDo9IHJlZ2V4Lm1hdGNoKGBeW15AXStAW15AXStcXC5bXkBdKyRgLCBleGFtcGxlX2VtYWlsXzEpXG5cbm1hdGNoXzIgOj0gcmVnZXgubWF0Y2goYF5bXkBdK0BbXkBdK1xcLlteQF0rJGAsIGV4YW1wbGVfZW1haWxfMilcblxubWF0Y2hfMyA6PSByZWdleC5tYXRjaChgXlteQF0rQFteQF0rXFwuW15AXSskYCwgaW5wdXQuZW1haWwpXG4ifQ==)

Path-based access

Managing access control in web applications is crucial for security. The following example uses Rego's `regex.match` to define role-based access to different URL paths. By associating URL patterns with user roles like "intern" and "admin," it ensures that users only access authorized paths.

policy.rego

```
package playimport rego.v1news_pattern := `^/news/.*`admin_pattern := `^/admin/.*`path_patterns := {	"intern": {news_pattern},	"admin": {news_pattern, admin_pattern},}default allow := falseallow if {	some pattern in path_patterns[input.role]	regex.match(pattern, input.path)}
```

Output

{
  "admin\_pattern": "^/admin/.\*",
  "allow": false,
  "news\_pattern": "^/news/.\*",
  "path\_patterns": {
    "admin": \[
      "^/admin/.\*",
      "^/news/.\*"
    \],
    "intern": \[
      "^/news/.\*"
    \]
  }
}

input.json

```
{  "role": "intern",  "path": "/admin/staff/123/salary"}
```

data.json

```
{}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcInJvbGVcIjogXCJpbnRlcm5cIixcbiAgXCJwYXRoXCI6IFwiL2FkbWluL3N0YWZmLzEyMy9zYWxhcnlcIlxufSIsImQiOiJ7fSIsInAiOiJwYWNrYWdlIHBsYXlcblxuaW1wb3J0IHJlZ28udjFcblxubmV3c19wYXR0ZXJuIDo9IGBeL25ld3MvLipgXG5cbmFkbWluX3BhdHRlcm4gOj0gYF4vYWRtaW4vLipgXG5cbnBhdGhfcGF0dGVybnMgOj0ge1xuXHRcImludGVyblwiOiB7bmV3c19wYXR0ZXJufSxcblx0XCJhZG1pblwiOiB7bmV3c19wYXR0ZXJuLCBhZG1pbl9wYXR0ZXJufSxcbn1cblxuZGVmYXVsdCBhbGxvdyA6PSBmYWxzZVxuXG5hbGxvdyBpZiB7XG5cdHNvbWUgcGF0dGVybiBpbiBwYXRoX3BhdHRlcm5zW2lucHV0LnJvbGVdXG5cdHJlZ2V4Lm1hdGNoKHBhdHRlcm4sIGlucHV0LnBhdGgpXG59XG4ifQ==)

Validating user text input

Text provided by users is often unstructured and untrusted. To ensure that the data is both safe to use and error-free, `regex.match()` can be used to validate the data against a simple pattern.

data.json

```
{}
```

input.json

```
{}
```

policy.rego

```
package playimport rego.v1name_pattern := `^(\p{L}+\s?)+\p{L}+$`valid_name1 := regex.match(name_pattern, "Juan Pérez")valid_name2 := regex.match(name_pattern, "张伟")invalid_name1 := regex.match(name_pattern, "Juan ")invalid_name2 := regex.match(name_pattern, "- 张伟")
```

Output

{
  "invalid\_name1": false,
  "invalid\_name2": false,
  "name\_pattern": "^(\\\\p{L}+\\\\s?)+\\\\p{L}+$",
  "valid\_name1": true,
  "valid\_name2": true
}

Case insensitive matching

Sometimes data can be supplied in a variety of cases, and matches need to be the same regardless of case. One example of this when matching GitHub usernames.

This is where the `(?i)` modifier comes in. In the following example we can see how repositories with different cases are matched.

policy.rego

```
package playimport rego.v1matching_repos contains repo if {	some repo, url in input.repos	regex.match(`(?i)^github.com\/styrainc\/`, url)}
```

Output

{
  "matching\_repos": \[
    "demos",
    "enterprise-opa",
    "regal"
  \]
}

input.json

```
{  "repos": {    "regal": "github.com/styrainc/regal",    "demos": "github.com/StyraInc/opa-sdk-demos",    "enterprise-opa": "github.com/styrainc/enterprise-opa",    "opa": "github.com/open-policy-agent/opa"  }}
```

data.json

```
{}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcInJlcG9zXCI6IHtcbiAgICBcInJlZ2FsXCI6IFwiZ2l0aHViLmNvbS9zdHlyYWluYy9yZWdhbFwiLFxuICAgIFwiZGVtb3NcIjogXCJnaXRodWIuY29tL1N0eXJhSW5jL29wYS1zZGstZGVtb3NcIixcbiAgICBcImVudGVycHJpc2Utb3BhXCI6IFwiZ2l0aHViLmNvbS9zdHlyYWluYy9lbnRlcnByaXNlLW9wYVwiLFxuICAgIFwib3BhXCI6IFwiZ2l0aHViLmNvbS9vcGVuLXBvbGljeS1hZ2VudC9vcGFcIlxuICB9XG59IiwiZCI6Int9IiwicCI6InBhY2thZ2UgcGxheVxuXG5pbXBvcnQgcmVnby52MVxuXG5tYXRjaGluZ19yZXBvcyBjb250YWlucyByZXBvIGlmIHtcblx0c29tZSByZXBvLCB1cmwgaW4gaW5wdXQucmVwb3NcblxuXHRyZWdleC5tYXRjaChgKD9pKV5naXRodWIuY29tXFwvc3R5cmFpbmNcXC9gLCB1cmwpXG59XG4ifQ==)

tip

Here are the common modifiers for regular expressions:

| Flag | Description |
| --- | --- |
| `i` | case-insensitive (default false) |
| `m` | multi-line mode: `^` and `$` match begin/end line in addition to begin/end text |
| `s` | let `.` match `\n` (default false) |

Read more here on the [RE2 Wiki](https://github.com/google/re2/wiki/Syntax).

### `template_match`

`regex.template_match()` is an advanced function for matching inputs against complex patterns. Sometimes, an input string needs to be validated as a series of distinct components. This function allows you to offer patterns to validate specific parts of the string separately.

warning

Before continuing, make sure your use case is not solved by the simpler [`regex.match()`](#match) or [`glob.match`](/docs/policy-reference/builtins/glob#builtin-glob-globmatch) functions.

This functions are easier to use and thus less error prone for simpler use cases.

Advanced path pattern matching

In the example that follows, we have a complex path which represents an AWS ARN owned by a project with a UUID v4 identifier. The path is validated in two parts using two separate patterns, each contained to particular segments of the path.

data.json

```
{}
```

input.json

```
{}
```

policy.rego

```
package playimport rego.v1uuid_v4_pattern := `[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`aws_arn_pattern := `arn:(aws[a-zA-Z-]*):([a-zA-Z0-9-]+):([a-zA-Z0-9-]*):([0-9]*):([a-zA-Z0-9-:/]+)`path := "/projects/10ceef56-2b18-4cf7-895f-14d2dc45cc66/arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0"path_pattern_template := sprintf("/projects/{%s}/{%s}", [	uuid_v4_pattern,	aws_arn_pattern,])matches := regex.template_match(path_pattern_template, path, "{", "}")
```

Output

{
  "aws\_arn\_pattern": "arn:(aws\[a-zA-Z-\]\*):(\[a-zA-Z0-9-\]+):(\[a-zA-Z0-9-\]\*):(\[0-9\]\*):(\[a-zA-Z0-9-:/\]+)",
  "matches": true,
  "path": "/projects/10ceef56-2b18-4cf7-895f-14d2dc45cc66/arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0",
  "path\_pattern\_template": "/projects/{\[0-9a-f\]{8}-\[0-9a-f\]{4}-4\[0-9a-f\]{3}-\[89ab\]\[0-9a-f\]{3}-\[0-9a-f\]{12}}/{arn:(aws\[a-zA-Z-\]\*):(\[a-zA-Z0-9-\]+):(\[a-zA-Z0-9-\]\*):(\[0-9\]\*):(\[a-zA-Z0-9-:/\]+)}",
  "uuid\_v4\_pattern": "\[0-9a-f\]{8}-\[0-9a-f\]{4}-4\[0-9a-f\]{3}-\[89ab\]\[0-9a-f\]{3}-\[0-9a-f\]{12}"
}

### `find_all_string_submatch_n`

`regex.find_all_string_submatch_n()` is an advanced function for matching inputs against patterns with capture groups. This function returns a list matches, where matches are themselves lists of strings containing the full match followed by each of the submatches.

warning

Before continuing, make sure your use case is not solved by the simpler [`regex.match()`](#match) function.

This function is easier to use and thus less error prone for simpler use cases.

Controlling Plus Addressing in Emails

In the example that follows, we show a policy that uses the `regex.find_all_string_submatch_n` built-in to extract the 'plus suffix', if present, from an email address.

This policy ensures that plus addresses are only permitted for use by internal users to avoid potential abuse.

policy.rego

```
package playimport rego.v1internal_domain := "example.com"allow if count(deny) == 0deny contains "plus addressing not allowed unless internal" if {	email_matches[1] != ""	email_matches[2] != internal_domain}email_matches := regex.find_all_string_submatch_n(`^[^+@]+(\+[^@]*)?@([^@]+)$`, input.email, 1)[0]
```

Output

{
  "allow": true,
  "deny": \[\],
  "email\_matches": \[
    "foo+test@example.com",
    "+test",
    "example.com"
  \],
  "internal\_domain": "example.com"
}

input.json

```
{  "email": "foo+test@example.com"}
```

data.json

```
{}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcImVtYWlsXCI6IFwiZm9vK3Rlc3RAZXhhbXBsZS5jb21cIlxufSIsImQiOiJ7fSIsInAiOiJwYWNrYWdlIHBsYXlcblxuaW1wb3J0IHJlZ28udjFcblxuaW50ZXJuYWxfZG9tYWluIDo9IFwiZXhhbXBsZS5jb21cIlxuXG5hbGxvdyBpZiBjb3VudChkZW55KSA9PSAwXG5cbmRlbnkgY29udGFpbnMgXCJwbHVzIGFkZHJlc3Npbmcgbm90IGFsbG93ZWQgdW5sZXNzIGludGVybmFsXCIgaWYge1xuXHRlbWFpbF9tYXRjaGVzWzFdICE9IFwiXCJcblx0ZW1haWxfbWF0Y2hlc1syXSAhPSBpbnRlcm5hbF9kb21haW5cbn1cblxuZW1haWxfbWF0Y2hlcyA6PSByZWdleC5maW5kX2FsbF9zdHJpbmdfc3VibWF0Y2hfbihgXlteK0BdKyhcXCtbXkBdKik/QChbXkBdKykkYCwgaW5wdXQuZW1haWwsIDEpWzBdXG4ifQ==)

Parsing of scopes

Here we see how `regex.find_all_string_submatch_n` can be used to create structured data from unstructured text. In this example, we parse a list of scopes from a string and use that to create an object we can use in policies to look up permissions.

policy.rego

```
package playimport rego.v1scope_pattern := `(\w+):(\w+)`scope_map[scope[2]] := scope[1] if {	some scope in regex.find_all_string_submatch_n(scope_pattern, input.token.payload.scopes, -1)}resource := split(input.path, "/")[1]default allow := falseallow if {	input.method == "GET"	scope_map[resource] in {"read", "write"}}
```

Output

{
  "allow": true,
  "resource": "users",
  "scope\_map": {
    "comments": "delete",
    "posts": "write",
    "users": "read"
  },
  "scope\_pattern": "(\\\\w+):(\\\\w+)"
}

input.json

```
{  "path": "/users/1234567890",  "method": "GET",  "token": {    "header": {      "alg": "HS256",      "typ": "JWT"    },    "payload": {      "sub": "1234567890",      "name": "John Doe",      "iat": 1516239022,      "scopes": "read:users write:posts delete:comments"    },    "signature": "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"  }}
```

data.json

```
{}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcInBhdGhcIjogXCIvdXNlcnMvMTIzNDU2Nzg5MFwiLFxuICBcIm1ldGhvZFwiOiBcIkdFVFwiLFxuICBcInRva2VuXCI6IHtcbiAgICBcImhlYWRlclwiOiB7XG4gICAgICBcImFsZ1wiOiBcIkhTMjU2XCIsXG4gICAgICBcInR5cFwiOiBcIkpXVFwiXG4gICAgfSxcbiAgICBcInBheWxvYWRcIjoge1xuICAgICAgXCJzdWJcIjogXCIxMjM0NTY3ODkwXCIsXG4gICAgICBcIm5hbWVcIjogXCJKb2huIERvZVwiLFxuICAgICAgXCJpYXRcIjogMTUxNjIzOTAyMixcbiAgICAgIFwic2NvcGVzXCI6IFwicmVhZDp1c2VycyB3cml0ZTpwb3N0cyBkZWxldGU6Y29tbWVudHNcIlxuICAgIH0sXG4gICAgXCJzaWduYXR1cmVcIjogXCJTZmxLeHdSSlNNZUtLRjJRVDRmd3BNZUpmMzZQT2s2eUpWX2FkUXNzdzVjXCJcbiAgfVxufSIsImQiOiJ7fSIsInAiOiJwYWNrYWdlIHBsYXlcblxuaW1wb3J0IHJlZ28udjFcblxuc2NvcGVfcGF0dGVybiA6PSBgKFxcdyspOihcXHcrKWBcblxuc2NvcGVfbWFwW3Njb3BlWzJdXSA6PSBzY29wZVsxXSBpZiB7XG5cdHNvbWUgc2NvcGUgaW4gcmVnZXguZmluZF9hbGxfc3RyaW5nX3N1Ym1hdGNoX24oc2NvcGVfcGF0dGVybiwgaW5wdXQudG9rZW4ucGF5bG9hZC5zY29wZXMsIC0xKVxufVxuXG5yZXNvdXJjZSA6PSBzcGxpdChpbnB1dC5wYXRoLCBcIi9cIilbMV1cblxuZGVmYXVsdCBhbGxvdyA6PSBmYWxzZVxuXG5hbGxvdyBpZiB7XG5cdGlucHV0Lm1ldGhvZCA9PSBcIkdFVFwiXG5cdHNjb3BlX21hcFtyZXNvdXJjZV0gaW4ge1wicmVhZFwiLCBcIndyaXRlXCJ9XG59XG4ifQ==)

### `globs_match`

`regex.globs_match()` is a less commonly used built-in function that checks if two patterns overlap. This can be useful when using patterns to define permissions or access control rules. The function returns `true` if the two patterns overlap and `false` otherwise.

Pattern based access

This example demonstrates using `regex.globs_match` in Rego to ensure actions are allowed only if the user's permissions overlap with the required permissions for the action. The user's permissions are defined by patterns, as are the permissions required by any given action.

policy.rego

```
package playimport rego.v1user_roles := data.user_roles[input.user_id]action_requirements := data.action_requirements[input.action]permission_patterns contains pattern if {	some role in user_roles	some pattern in data.role_permissions[role]}default allow := falseallow if {	every requirement in action_requirements {		some pattern in permission_patterns		regex.globs_match(pattern, requirement)	}}
```

Output

{
  "action\_requirements": \[
    "dns.records.create",
    "compute.containers.create",
    "compute.containers.scale.\*"
  \],
  "allow": true,
  "permission\_patterns": \[
    "compute.\*",
    "dns.\*"
  \],
  "user\_roles": \[
    "developer"
  \]
}

input.json

```
{  "user_id": "c2655539-8422-476d-9430-a26a4efa51b2",  "action": "tenant.create",  "props": {    "name": "my-new-tenant"  }}
```

data.json

```
{  "user_roles": {    "c2655539-8422-476d-9430-a26a4efa51b2": [      "developer"    ]  },  "role_permissions": {    "developer": [      "dns.*",      "compute.*"    ]  },  "action_requirements": {    "tenant.create": [      "dns.records.create",      "compute.containers.create",      "compute.containers.scale.*"    ]  }}
```

[Open in OPA Playground](https://play.openpolicyagent.org/?state=eyJpIjoie1xuICBcInVzZXJfaWRcIjogXCJjMjY1NTUzOS04NDIyLTQ3NmQtOTQzMC1hMjZhNGVmYTUxYjJcIixcbiAgXCJhY3Rpb25cIjogXCJ0ZW5hbnQuY3JlYXRlXCIsXG4gIFwicHJvcHNcIjoge1xuICAgIFwibmFtZVwiOiBcIm15LW5ldy10ZW5hbnRcIlxuICB9XG59IiwiZCI6IntcbiAgXCJ1c2VyX3JvbGVzXCI6IHtcbiAgICBcImMyNjU1NTM5LTg0MjItNDc2ZC05NDMwLWEyNmE0ZWZhNTFiMlwiOiBbXG4gICAgICBcImRldmVsb3BlclwiXG4gICAgXVxuICB9LFxuICBcInJvbGVfcGVybWlzc2lvbnNcIjoge1xuICAgIFwiZGV2ZWxvcGVyXCI6IFtcbiAgICAgIFwiZG5zLipcIixcbiAgICAgIFwiY29tcHV0ZS4qXCJcbiAgICBdXG4gIH0sXG4gIFwiYWN0aW9uX3JlcXVpcmVtZW50c1wiOiB7XG4gICAgXCJ0ZW5hbnQuY3JlYXRlXCI6IFtcbiAgICAgIFwiZG5zLnJlY29yZHMuY3JlYXRlXCIsXG4gICAgICBcImNvbXB1dGUuY29udGFpbmVycy5jcmVhdGVcIixcbiAgICAgIFwiY29tcHV0ZS5jb250YWluZXJzLnNjYWxlLipcIlxuICAgIF1cbiAgfVxufSIsInAiOiJwYWNrYWdlIHBsYXlcblxuaW1wb3J0IHJlZ28udjFcblxudXNlcl9yb2xlcyA6PSBkYXRhLnVzZXJfcm9sZXNbaW5wdXQudXNlcl9pZF1cblxuYWN0aW9uX3JlcXVpcmVtZW50cyA6PSBkYXRhLmFjdGlvbl9yZXF1aXJlbWVudHNbaW5wdXQuYWN0aW9uXVxuXG5wZXJtaXNzaW9uX3BhdHRlcm5zIGNvbnRhaW5zIHBhdHRlcm4gaWYge1xuXHRzb21lIHJvbGUgaW4gdXNlcl9yb2xlc1xuXHRzb21lIHBhdHRlcm4gaW4gZGF0YS5yb2xlX3Blcm1pc3Npb25zW3JvbGVdXG59XG5cbmRlZmF1bHQgYWxsb3cgOj0gZmFsc2VcblxuYWxsb3cgaWYge1xuXHRldmVyeSByZXF1aXJlbWVudCBpbiBhY3Rpb25fcmVxdWlyZW1lbnRzIHtcblx0XHRzb21lIHBhdHRlcm4gaW4gcGVybWlzc2lvbl9wYXR0ZXJuc1xuXHRcdHJlZ2V4Lmdsb2JzX21hdGNoKHBhdHRlcm4sIHJlcXVpcmVtZW50KVxuXHR9XG59XG4ifQ==)

## Performance Metrics

When `?metrics=true` is specified in API requests, regex operations expose the following per-query metrics:

| Metric | Description |
| --- | --- |
| `counter_rego_builtin_regex_interquery_value_cache_hits` | Number of compiled regex patterns served from the inter-query value cache. Only present when [inter-query value caching](/docs/configuration#caching) is enabled and a previously compiled pattern is reused |

## Footnotes

1.  Read more about the [RE2 syntax](https://github.com/google/re2/wiki/Syntax) [↩](#user-content-fnref-1)
    
2.  See [non-raw Regex Regal rule](/projects/regal/rules/idiomatic/non-raw-regex-pattern). [↩](#user-content-fnref-2)