# llLinksetDataFindKeys

*LSL function*

```lsl
list list llLinksetDataFindKeys(string pattern, integer start, integer count);
```

- `string pattern`: A regular expression (regex) describing which keys to search for.
- `integer start`: Zero-based start index of the matching keys to return.
- `integer count`: Maximum number of keys to return (or less than 1 to retrieve all matching keys).

- Returns: `list`
- Energy: 10

The **`llLinksetDataFindKeys`** function returns a list of up to **count** keys from the datastore that match **pattern**, starting at the one indicated by **start**. If **count** is less than 1, then all keys between **start** and the end which match **pattern** are returned. If **count** minus **start** exceeds the number of matching keys, the returned list will be shorter than **count**, down to a zero-length list if **start** equals or exceeds the number of matching keys. The list is ordered alphabetically.

Returns a [list](https://wiki.secondlife.com/wiki/list) of the keys in the datastore.

```lsl title="How to use" frame="terminal"
list result = llLinksetDataFindKeys("", 0, 0);
```

## Specification

**pattern** is a [Regular expression](https://en.wikipedia.org/wiki/Regular_expression).

## Caveats

- The maximum length for **pattern** seems to be 800 characters.
- There seems to be a timing restriction. If the time limit is exceeded, the function fails silently.
- Returns an empty list and the script continues execution.
- To delete keys matching an expression, use the similar [llLinksetDataDeleteFound](/functions/llLinksetDataDeleteFound/).

## Examples

<details open>
<summary>When **pattern** matches multiple keys, **start** can be used to skip over some of the first matches.</summary>

```lsl collapse={1-11}
default
{
    state_entry()
    {
        llLinksetDataWrite("ThingA_config", "value");
        llLinksetDataWrite("ThingA_data",   "value");
        llLinksetDataWrite("ThingB_config", "value");
        llLinksetDataWrite("ThingB_data",   "value");
        llLinksetDataWrite("ThingC_config", "value");
        llLinksetDataWrite("ThingC_data",   "value");
        list keys;

        // Return 1 key starting from the first match.
        keys = llLinksetDataFindKeys("Thing", 0, 1);
        llOwnerSay(llList2CSV(keys)); // ThingA_config

        // Return 1 key after skipping the first 3 matches.
        keys = llLinksetDataFindKeys("Thing", 3, 1);
        llOwnerSay(llList2CSV(keys)); // ThingB_data

        // Return up to 10 keys after skipping the first match.
        keys = llLinksetDataFindKeys("_data", 1, 10);
        llOwnerSay(llList2CSV(keys)); // ThingB_data, ThingC_data
    }
}
```

</details>

<details>
<summary>The following regular expression code can be used to find UUID keys. (Such as those use to identify user UUID)</summary>

```lsl
        list keysFound = llLinksetDataFindKeys("(?i)^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$",  0, 0);
```

</details>

<details>
<summary>The following code can also be used to find UUID keys in LinksetData memory.</summary>

```lsl
        list keysFound = llLinksetDataFindKeys("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",  0, 0);
```

</details>

<details>
<summary>*Warning: Keep track of how many UUIDs will be returned, as too many can overwhelm script memory and cause a stack-heap crash.*</summary>

The script below uses `llLinksetDataFindKeys` for blacklist management.

```lsl collapse={1-79, 85-108, 118-129}
integer gDialogChannel;
integer gDialogHandle;
integer gManagingBlocks;

startDialog(key person)
{
    gManagingBlocks = 0;
    gDialogHandle = llListen(gDialogChannel, "", person, "");
    llDialog(person, "\nSelect action", ["List blocks", "Add block", "Remove block"], gDialogChannel);
    llSetTimerEvent(60);
}

stopDialog()
{
    llSetTimerEvent(0);
    llListenRemove(gDialogHandle);
}

default
{

    on_rez(integer sp)
    {
        llResetScript();
    }

    state_entry()
    {
        gDialogChannel = (integer)(llFrand(-10000000)-10000000);
        llListen(PUBLIC_CHANNEL, "", NULL_KEY, "");;
    }

    timer()
    {
        stopDialog();
    }

    touch_start(integer nd)
    {
        key toucherKey = llDetectedKey(0);
        if (toucherKey == llGetOwner())
        {
            startDialog(toucherKey);
        }
    }

    listen(integer channel, string name, key id, string message)
    {

        if (llGetAgentSize(id) == ZERO_VECTOR)
        {
            return;
        }

        if (channel == gDialogChannel)
        {
            stopDialog();
            if (gManagingBlocks)
            {
                message = llStringTrim(message, STRING_TRIM);
                if ((key)message)
                {
                    if (gManagingBlocks == 1)
                    {
                        llOwnerSay("Addition request has been sent to the blacklist storage");
                        llLinksetDataWrite("blocklist:" + message, "1");
                    }
                    else
                    {
                        llOwnerSay("Removal request has been sent to the blacklist storage.");
                        llLinksetDataDelete("blocklist:" + message);
                    }
                }
                else
                {
                    llOwnerSay("The UUID '" + message + "' appears to be invalid.");
                }
                startDialog(id);
            }
            else if (message == "List blocks")
            {
                list blocks = llLinksetDataFindKeys("^blocklist:", 0, 0);
                integer listLength = llGetListLength(blocks);
                llOwnerSay("Blacklist items: " + (string)listLength);
                integer i;
                while (i < listLength)
                {
                    string record = llGetSubString(llList2String(blocks, i), 10, -1);
                    llOwnerSay("- secondlife:///app/agent/" + record + "/about" + " - " + record);
                    ++i;
                }
                blocks = [];
                startDialog(id);
            }
            else if (message == "Add block" || message == "Remove block")
            {
                string label = "add to";
                gManagingBlocks = 1;
                if (message == "Remove block")
                {
                    gManagingBlocks = 2;
                    label = "remove from";
                }
                gDialogHandle = llListen(gDialogChannel, "", id, "");
                llTextBox(id, "\nPlease specify one single avatar UUID you'd like to " + label + " the blacklist storage.", gDialogChannel);
                llSetTimerEvent(60);
            }
            return;
        }

        if (llGetListLength(llLinksetDataFindKeys("blocklist:" + (string)id, 0, 1)) > 0)
        {
            llRegionSayTo(id, 0, "You're blacklisted.");
            return;
        }

        llRegionSayTo(id, 0, "Hello there, secondlife:///app/agent/" + (string)id + "/about - your message: " + message);

    }

    linkset_data(integer action, string name, string value)
    {
        if (action == LINKSETDATA_RESET || action == LINKSETDATA_DELETE || action == LINKSETDATA_UPDATE)
        {
            llOwnerSay("Blacklist storage modified.");
        }
    }

}
```

</details>

## Notes

#### Regular Expression Cheat Sheet

## See also

### Functions

- [llLinksetDataAvailable](/functions/llLinksetDataAvailable/)
- [llLinksetDataCountFound](/functions/llLinksetDataCountFound/)
- [llLinksetDataCountKeys](/functions/llLinksetDataCountKeys/)
- [llLinksetDataDelete](/functions/llLinksetDataDelete/)
- [llLinksetDataDeleteFound](/functions/llLinksetDataDeleteFound/)
- [llLinksetDataListKeys](/functions/llLinksetDataListKeys/)
- [llLinksetDataRead](/functions/llLinksetDataRead/)
- [llLinksetDataReset](/functions/llLinksetDataReset/)
- [llLinksetDataWrite](/functions/llLinksetDataWrite/)

---

*Source: [LlLinksetDataFindKeys](https://wiki.secondlife.com/wiki/LlLinksetDataFindKeys) on the Second Life Wiki. Content from the Second Life Wiki article LlLinksetDataFindKeys (revision 1219033, 2026-09-10), CC BY-SA 3.0.*

---

From lsl.dev: https://lsl.dev/functions/llLinksetDataFindKeys/
