# Generate Strings

This operation returns **strings** matched by the Term rather than another Term, which makes it the usual way to turn a specification into test data or fixtures.

The strings are **distinct** within a call, and you control how many are returned and where in the language they come from.

## Basic usage

The two main parameters are:

* `limit`: the maximum number of distinct strings to return, between 1 and 100
* `offset`: the number of strings to skip before collecting results, useful for pagination

You get **fewer than `limit`** strings when the Term's language holds fewer than that.

<CodeTabs defaultValue="java">
<CodeTabs.Tab value="java" label="Java">
```java
RegexSolverClient client = RegexSolverClient.builder()
    .apiToken(System.getenv("REGEXSOLVER_API_TOKEN"))
    .build();

Term term = Term.regex("(alpha|beta|prod)-[a-z0-9]{4}");

// limit 5, offset 0: up to 5 distinct strings, skipping none
List<String> results = client.generateStrings(term, 5, 0);

System.out.println(results);
// ["beta-0000", "beta-0001", "beta-0002", "beta-0003", "beta-0004"]
```
</CodeTabs.Tab>

<CodeTabs.Tab value="javascript" label="JavaScript">
```javascript
const client = new RegexSolverClient({ apiToken: process.env.REGEXSOLVER_API_TOKEN });

const term = Term.regex("(alpha|beta|prod)-[a-z0-9]{4}");

// limit 5, offset 0: up to 5 distinct strings, skipping none
const results = await client.generateStrings(term, 5, 0);

console.log(results);
// ["beta-0000", "beta-0001", "beta-0002", "beta-0003", "beta-0004"]
```
</CodeTabs.Tab>

<CodeTabs.Tab value="python" label="Python">
```python
client = RegexSolverClient(api_token=os.getenv("REGEXSOLVER_API_TOKEN"))

term = Term.regex(r"(alpha|beta|prod)-[a-z0-9]{4}")

# limit 5, offset 0: up to 5 distinct strings, skipping none
results = client.generate_strings(term, 5, 0)

print(results)
# ['beta-0000', 'beta-0001', 'beta-0002', 'beta-0003', 'beta-0004']
```
</CodeTabs.Tab>
</CodeTabs>

Notice that all five strings share the same **path**: a path is one of the shapes the Term allows, here `beta-____`. By default, generation expands one path in full, shortest first, before moving to the next one, which is the cheapest way to page through a whole language but makes a small sample look repetitive. [String Generation Ordering](/advance-usage/generation-ordering) covers how to spread a sample across paths and shuffle it into natural-looking data.

<Callout type="caution">
Paginating with `offset` only returns a consistent sequence of strings if the Term's automaton is **deterministic**. If you only ever read from offset 0, this does not affect you. See [Determinism](/advance-usage/determinism).
</Callout>

## Bounding string length

`minLength` and `maxLength` restrict generation to strings within a length window. Excluded strings are never enumerated at all, so they do not consume `offset` positions either.

<CodeTabs defaultValue="java">
<CodeTabs.Tab value="java" label="Java">
```java
Term term = Term.regex("(ab|cde)*");

GenerateStringsOptions options = GenerateStringsOptions.builder()
    .minLength(4)
    .maxLength(6);
List<String> results = client.generateStrings(term, 5, 0, options);

System.out.println(results);
// ["abab", "cdeab", "abcde", "ababab", "cdecde"]
```
</CodeTabs.Tab>

<CodeTabs.Tab value="javascript" label="JavaScript">
```javascript
const term = Term.regex("(ab|cde)*");

const results = await client.generateStrings(term, 5, 0, {
    minLength: 4,
    maxLength: 6,
});

console.log(results);
// ["abab", "cdeab", "abcde", "ababab", "cdecde"]
```
</CodeTabs.Tab>

<CodeTabs.Tab value="python" label="Python">
```python
term = Term.regex(r"(ab|cde)*")

results = client.generate_strings(term, 5, 0, min_length=4, max_length=6)

print(results)
# ['abab', 'cdeab', 'abcde', 'ababab', 'cdecde']
```
</CodeTabs.Tab>
</CodeTabs>

## Restricting the character set

`charset` restricts generation to a set of characters, given as a character class such as `[a-z]` or `\P{C}`. Paths needing a character outside of it are dropped entirely, so the strings they would have produced are never enumerated and do not consume `offset` positions either. When you omit it, every character the Term allows is used.

This is the practical way to keep generated data printable or ASCII-only when the Term itself allows the whole of Unicode.

<CodeTabs defaultValue="java">
<CodeTabs.Tab value="java" label="Java">
```java
Term term = Term.regex("[a-z]{3}");

GenerateStringsOptions options = GenerateStringsOptions.builder()
    .charset("[a-c]");
List<String> results = client.generateStrings(term, 5, 0, options);

System.out.println(results);
// ["aaa", "aab", "aac", "aba", "abb"]
```
</CodeTabs.Tab>

<CodeTabs.Tab value="javascript" label="JavaScript">
```javascript
const term = Term.regex("[a-z]{3}");

const results = await client.generateStrings(term, 5, 0, {
    charset: "[a-c]",
});

console.log(results);
// ["aaa", "aab", "aac", "aba", "abb"]
```
</CodeTabs.Tab>

<CodeTabs.Tab value="python" label="Python">
```python
term = Term.regex(r"[a-z]{3}")

results = client.generate_strings(term, 5, 0, charset="[a-c]")

print(results)
# ['aaa', 'aab', 'aac', 'aba', 'abb']
```
</CodeTabs.Tab>
</CodeTabs>

## Going further

Try the options interactively in the [live demo](https://regexsolver.com/demo?op=strings), or read [String Generation Ordering](/advance-usage/generation-ordering) for the full set.
