# How the `{?}` Placeholder Enables Multiple Username Variant Checking in Sherlock

> Discover how the {?} placeholder in Sherlock automatically generates username variants using separators like underscore, hyphen, and dot for efficient checking.

- Repository: [Sherlock/sherlock](https://github.com/sherlock-project/sherlock)
- Tags: internals
- Published: 2026-03-02

---

**Sherlock expands a single search pattern into multiple concrete usernames by interpreting the special `{?}` placeholder as a variable separator that generates underscore, hyphen, and dot variants automatically.**

The `{?}` placeholder is a core feature in the [sherlock-project/sherlock](https://github.com/sherlock-project/sherlock) repository that eliminates manual enumeration of username variations. When you provide a pattern like `john{?}doe`, the tool automatically probes for `john_doe`, `john-doe`, and `john.doe` across supported platforms, enhancing the discovery of accounts that use different naming conventions.

## The Three-Step Variant Generation Process

Sherlock implements this capability through a coordinated three-step pipeline defined in [`sherlock_project/sherlock.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sherlock.py). Each step transforms the abstract pattern into concrete HTTP requests.

### Step 1: Detecting the Placeholder with `check_for_parameter`

The process begins with **`check_for_parameter(username)`**, which scans the input string for the presence of `{?}`. Located at lines 53-57 in [`sherlock_project/sherlock.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sherlock.py), this function returns `True` when the pattern requires expansion, triggering the variant generation logic.

```python
from sherlock_project import sherlock

pattern = "john{?}doe"
if sherlock.check_for_parameter(pattern):
    print("Placeholder detected - generating variants")

```

### Step 2: Generating Username Variants with `multiple_usernames`

When a placeholder is detected, **`multiple_usernames(username)`** (lines 62-68) replaces `{?}` with each character from the separator list `["_", "-", "."]`. This produces a Python list containing every possible username combination.

```python
variants = sherlock.multiple_usernames("john{?}doe")
print(variants)

# Output: ['john_doe', 'john-doe', 'john.doe']

```

### Step 3: Interpolating URLs with `interpolate_string`

Finally, **`interpolate_string(input_object, username)`** (lines 43-50) inserts each generated variant into the site's URL template. This function replaces the generic `{}` token—defined in [`sherlock_project/sites.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sites.py) (lines 27-31)—with the concrete username, preparing the final request URL.

```python
site_url = "https://example.com/users/{}"
for username in variants:
    final_url = sherlock.interpolate_string(site_url, username)
    print(final_url)

# Output:

# https://example.com/users/john_doe

# https://example.com/users/john-doe

# https://example.com/users/john.doe

```

## Complete Implementation Example

The main search loop coordinates these functions to dispatch separate HTTP requests for each variant. Here is the complete workflow demonstrating how Sherlock processes a single patterned query:

```python
from sherlock_project import sherlock

# Define the pattern with the {?} placeholder

username_pattern = "john{?}doe"

# Check if expansion is needed

if sherlock.check_for_parameter(username_pattern):
    # Generate all three variants

    usernames = sherlock.multiple_usernames(username_pattern)
    
    # Template from sites.py manifest

    url_template = "https://example.com/profile/{}"
    
    # Probe each variant

    for username in usernames:
        target_url = sherlock.interpolate_string(url_template, username)
        # Sherlock sends individual HTTP requests for each URL

        print(f"Checking: {target_url}")

```

## Key Source Files

Understanding the `{?}` placeholder requires familiarity with these specific files in the repository:

- **[`sherlock_project/sherlock.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sherlock.py)** – Contains `check_for_parameter()`, `multiple_usernames()`, and `interpolate_string()`, implementing the core variant expansion logic.
- **[`sherlock_project/sites.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sites.py)** – Defines the `{}` URL insertion token and site manifest structure (lines 27-31).
- **[`tests/test_ux.py`](https://github.com/sherlock-project/sherlock/blob/main/tests/test_ux.py)** – Unit tests verifying placeholder detection and username generation accuracy.
- **[`sherlock_project/__init__.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/__init__.py)** – Entry point integrating the variant checking into the CLI workflow.

## Summary

- The **`{?}` placeholder** triggers automatic expansion of username patterns into multiple variants.
- **`check_for_parameter()`** detects when expansion is required in [`sherlock_project/sherlock.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sherlock.py).
- **`multiple_usernames()`** generates three separator variants: underscore, hyphen, and dot.
- **`interpolate_string()`** binds each variant to site-specific URL templates containing the `{}` token.
- This architecture allows Sherlock to discover accounts across platforms using different naming conventions without requiring users to manually enumerate each possibility.

## Frequently Asked Questions

### What characters does the `{?}` placeholder replace?

The `{?}` placeholder expands into three specific characters: the **underscore** (`_`), **hyphen** (`-`), and **dot** (`.`). These are hardcoded in the `multiple_usernames()` function within [`sherlock_project/sherlock.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sherlock.py), covering the most common username separator conventions across social platforms.

### How does Sherlock handle multiple username variants during execution?

Sherlock treats each variant as a distinct query. After generating the list of usernames, the main search loop iterates through each variant and calls `interpolate_string()` to construct unique URLs, dispatching separate HTTP requests for every permutation. This ensures comprehensive coverage while maintaining the original search intent.

### Can I use multiple `{?}` placeholders in a single username pattern?

The current implementation in [`sherlock_project/sherlock.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sherlock.py) is designed to handle a single `{?}` occurrence per pattern. The `multiple_usernames()` function performs a straightforward replacement operation that would not generate combinatorial permutations for multiple placeholders.

### Where is the URL template token `{}` defined?

The `{}` token used for final URL interpolation is defined in **[`sherlock_project/sites.py`](https://github.com/sherlock-project/sherlock/blob/main/sherlock_project/sites.py)** at lines 27-31. This token serves as the insertion point where concrete usernames replace the generic placeholder after variant generation is complete.