# regexCount Guide

## Overview

`regexCount(value, regexPattern)` counts matches of a **JavaScript (ECMAScript) regular expression** in a string and returns a number (0, 1, 2, …). It’s ideal for richer checks such as case-insensitivity, alternatives (`x|y|z`), word boundaries (`\b`), and quantified patterns.

> **Scope:** `regexCount` **counts** matches. It does **not** extract matched text or transform data.

**Data type of output:** Number

**Syntax**

```
regexCount(value, regexPattern)
```

* **value**: string (e.g. `'text'`) or variable (e.g. `%TEXT`)
* **regexPattern**: a string or variable containing a JavaScript-flavoured (ECMAScript) regex in `/pattern/flags` format, e.g. `'/\b\d{5}(-\d{4})?\b/g'`
  * Regex pattern must be wrapped in forward slashes e.g. `'/`*`pattern`*`/'`
  * Flags can be added after the closing forward-slash e.g. `'/`*`pattern`*`/`*`flags`*`'`
  * Common flags:
    * `g` – global (count all matches)
    * `i` – case-insensitive

**Example**

`regexCount(%TEXT, '/cat/')`   //given a value of "My favourite animal is a cat." it will return `1`.

To convert this to a boolean to ensure the expression passes or fails, you can do the following:

`regexCount(%TEXT, '/cat/')>=1`        //Given the same sentence it will return `true`.

## Regex Library

Access a collection of example regex patterns to support learning or to incorporate into your knowledge graph logic.

<table data-full-width="true"><thead><tr><th width="196.73828125">Use case</th><th width="424.1875">Regex (includes escaping and single quotes)</th><th>Example input/output</th></tr></thead><tbody><tr><td>Count US Zip code</td><td><code>'/\b\d{5}(-\d{4})?\b/g'</code></td><td><p><code>12345</code> // returns 1</p><p><code>12345-6789</code> // returns 1</p><p><code>1234</code> //returns 1</p></td></tr><tr><td>Count UK postcodes</td><td><code>'/\b[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}\b/gi'</code></td><td><p><code>SW1A 1AA</code> // returns 1</p><p><code>Sw1a 1aa</code> // returns 1</p><p><code>D343 EEF</code> // returns 0</p></td></tr><tr><td>Count email addresses</td><td><code>'/[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}/gi'</code></td><td><p><code>john.smith@example.com</code> // returns 1</p><p><code>john.smith@example</code> // returns 0</p></td></tr><tr><td>Count UK National Insurance Number</td><td><code>'/[A-CEGHJ-PR-TW-Z]{2}\d{6}[A-D]/g'</code></td><td><code>AB123456C, ZZ000000A, invalidNINumber</code> // returns 2</td></tr><tr><td>Count occurrences of words from a list</td><td><code>'/\b(apples|bananas|grapes|oranges|pears)\b/g'</code></td><td><code>I like apples, grapes, and oranges</code> // returns 3</td></tr><tr><td>Count dates (YYYY-MM-DD format)</td><td><code>'/\d{4}-\d{2}-\d{2}/g'</code></td><td><code>Start: 2023-12-01, End: 2024-01-20, Next: 2025-06-11</code> // returns 3</td></tr><tr><td>Validate that a string contains only letters and spaces</td><td><code>'/^[A-Za-z ]+$/'</code></td><td><p><code>John Smith</code> // returns 1</p><p><code>John M. Smith</code> // returns 0</p></td></tr></tbody></table>

## Troubleshooting

<table><thead><tr><th>Problem</th><th valign="top">Fix</th></tr></thead><tbody><tr><td><p>The following expression resulted in an error message</p><p></p><p><strong>Function:</strong> <code>regexCount(%S, 'cat')</code><br></p><p><strong>Error message:</strong> <code>Expression error at position 0 - In regexCount - Regex must be wrapped in slashes, e.g. `/abc/g`</code></p></td><td valign="top"><p>Wrap the regex in forward slashes<br></p><p><code>regexCount(%S, '/cat/')</code></p><p><br></p></td></tr><tr><td><p>The following expression found 0 matches when using a subject of cat:<br></p><p><code>regexCount(%S, '/Cat | cat/')</code></p><p><br></p></td><td valign="top"><p>Remove the spaces within the regex</p><p></p><p><code>regexCount(%S, '/Cat|cat/')</code></p></td></tr><tr><td><p>The following found 0 matches when using a subject of Cat (note: uppercase C):<br></p><p><code>regexCount(%S, '/cat/')</code></p></td><td valign="top"><p>Add the case-insensitive flag <code>i</code>  to ignore case<br></p><p><code>regexCount(%S, '/cat/i')</code> </p></td></tr><tr><td><p>Expecting a count greater than 1 to be returned for regexCount.<br>E.g. the following returns <code>1</code> but should be <code>2</code>.<br></p><p><code>regexCount('The weather was sunny and warm', '/hot|warm|nice|sunny|pleasant/i')</code></p></td><td valign="top">Add the global <code>g</code> flag to count all matches<br><br><code>regexCount('The weather was sunny and warm', '/hot|warm|nice|sunny|pleasant/gi')</code></td></tr></tbody></table>

## Error messages

If the engine hits an error at runtime, the regexCount function returns a **negative number**:

Below shows the current list of errors and their error codes:

| Error code | Name              | Description                                        |
| ---------- | ----------------- | -------------------------------------------------- |
| -1         | Unsafe            | Vulnerable regex pattern                           |
| -2         | Evaluation failed | Error at runtime                                   |
| -3         | Invalid syntax    | Regex failed to compile                            |
| -4         | Pattern exceeded  | Pattern length > max allowed (max 500 characters)  |
| -5         | Input exceeded    | Input string too long (max 10,000 characters)      |
| -6         | Invalid format    | Not in \`/pattern/flags\` format                   |
| -7         | Check timeout     | ReDos (excessive processing time) analysis timeout |

{% hint style="info" %}
During development, you may want to create a relationship with a rule that enables easy testing of inputs and outputs of the function, before embedding it into the business logic.

This will enable you to validate the regex function and surface any error codes.
{% endhint %}

## External resources

Below contains a selection of external tools that be used to learn, build and test regular expressions before incorporating into your knowledge graph.

* [RegExr](https://regexr.com/) - An online tool to learn, build and test Regular Expressions
* [Regex tester](https://regex101.com/) - An online regex builder/debugger
* [Regex interactive tutorial](https://regexlearn.com/) - An online interactive tutorial, cheat sheet & playground
* [Regex visualizer](https://extendsclass.com/regex-tester.html) - An online visual regex tester

A recommended workflow for those unfamiliar with regex includes:

1. Use your favourite LLM (e.g. ChatGPT or Claude) to build a regex based on your requirements
2. Use [Regex tester](https://regex101.com/) to test this regex with the data you expect to be using. Ask for refinements where required.
3. Create a knowledge graph with one relationship of (Data) > has regexCounts > (Number of matches) (Data must be `string`. Number of matches must be a `number`)
4. Create a rule with a single expression containing regexCount with the result being assigned to the object (%O).
5. Querying this relationship enables you to pass test data in the subject and confirm how many matches are found as the result.

<figure><img src="/files/XNogqR1NRA1WdFl6sXE5" alt=""><figcaption></figcaption></figure>

## Regex in the Evidence Tree

To ensure the evidence tree is easier to understand [evidence text](/rainbird/knowledge-modelling/modelling-features/relationships/rules.md#evidence-text) (aka alt-text) can be added to expressions containing a regular expression.

**Without evidence text:**

<figure><img src="/files/SDr3MBvzB0yr7XLxcrQp" alt=""><figcaption></figcaption></figure>

**With evidence text:**

<figure><img src="/files/Q7APfoph4Hj4RLDiz8qJ" alt=""><figcaption></figcaption></figure>

## Advanced: Building a dynamic regex pattern

Using an intermediary expression you can compose a regex pattern containing dynamic data in one expression, then use it in another.

The below example shows a rule that infers a person could be onboarded to a company, assuming their profile contains an email address from one of its approved suppliers.

This builds a regex pattern to match an email address structure, but only when it contains an approved supplier name in the email domain.

{% code fullWidth="true" %}

```
(Person) > approved for onboarding > True
when
%S > being onboarded to > %COMPANY
%S > has profile > %PROFILE                                        //%PROFILE contains unstructured data including name and contact details
%COMPANY > has approved suppliers > %APPROVED_SUPPLIER            //get approved supplier name
'/\b[A-Za-z0-9._%+-]+@(?:[A-Za-z0-9-]+\.)*' + %APPROVED_SUPPLIER + '\.[A-Za-z]{2,}\b/gi'    //regex pattern assigned to %REGEX variable
regexCount(%PROFILE, %REGEX) >= 1                                 //check if profile contains a valid email with approved supplier in the domain

```

{% endcode %}

Breaking down this dynamic regex, the goal was to create the following regex pattern (assuming Rainbird is the approved supplier):

```
/\b[A-Za-z0-9._%+-]+@(?:[A-Za-z0-9-]+\.)*Rainbird\.[A-Za-z]{2,}\b/gi
```

To insert Rainbird as a variable, the string needs to be split up either side of Rainbird, with Rainbird replaced with a variable. This is achieved using [string concatenation](/rainbird/knowledge-modelling/modelling-features/relationships/rules/expressions-list.md#string-concatenation):

> <mark style="color:purple;">'first part of string'</mark> <mark style="color:orange;">+ %VARIABLE +</mark> <mark style="color:purple;">'second part of string'</mark>
>
> <mark style="color:purple;">'/\b\[A-Za-z0-9.\_%+-]+@(?:\[A-Za-z0-9-]+\\.)\*'</mark> <mark style="color:orange;">+ %VARIABLE +</mark> <mark style="color:purple;">'\\.\[A-Za-z]{2,}\b/gi'</mark>

The output of this expression (the string containing a regex pattern) must be assigned to a variable that can be passed into the regexCount function.

{% hint style="info" %}
This is not supported as a nested operation within the regexCount function and MUST be built in a separate expression, with it being passed into the regexCount function as a variable.

When creating a dynamic regex pattern it is important to ensure the resulting regex pattern is wrapped in forwards slashes and conforms to the /pattern/flags structure.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rainbird.ai/rainbird/knowledge-modelling/modelling-features/relationships/rules/expressions-list/regexcount-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
