Skip to main content

Rego Built-in Function: regex.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() function.

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

Examples

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 play

import rego.v1

internal_domain := "example.com"

allow if count(deny) == 0

deny 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]
input.json
{
"email": "foo+test@example.com"
}
data.json
{}

Open in OPA Playground

RuleOutput ValueNotes
allowtrueThis user is allowed to use + addresses as they are internal
email_matches["foo+test@example.com","+test","example.com"]Observe that the first item is the full match

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 play

import rego.v1

scope_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 := false

allow if {
input.method == "GET"
scope_map[resource] in {"read", "write"}
}
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

RuleOutput ValueNotes
allowtrueThis user has read permissions for users
scope_map{"comments":"delete","posts":"write","users":"read"}