Skip to content

Improve StringReplace Op to support pipes for multiple search strings (with code) #1003

@kikohs

Description

@kikohs

Hello,
I've improved the StringReplace op to support the pipe operator if you want to search and replace for multiple patterns.

Maybe useful to integrate in core?
https://cables.gl/p/s20ERH

const
    inStr = op.inString("String"),
    inSearch = op.inString("Search For", "foo"),
    inRepl = op.inString("Replace", "bar"),
    inWhat = op.inSwitch("Replace What", ["All", "First"], "All"),
    inUsePipes = op.inBool("Handle Pipes as OR", true),
    inUseRegex = op.inBool("Enable RegExp", false),
    outStr = op.outString("Result");

inRepl.onChange =
inStr.onChange =
inWhat.onChange =
inSearch.onChange =
inUsePipes.onChange =
inUseRegex.onChange = update;

function update()
{
    op.setUiError("exception", null);

    let str = "";
    try
    {
        let searchPattern = inSearch.get();
        let inputString = String(inStr.get());

        // Handle different replacement strategies
        if (inUsePipes.get() && searchPattern.includes('|')) {
            // Split by pipe and handle each pattern
            const patterns = searchPattern.split('|')
                .map(pattern => pattern.trim());

            // If we're using regex, don't escape special chars
            if (!inUseRegex.get()) {
                patterns.forEach((pattern, index, arr) => {
                    arr[index] = escapeRegExp(pattern);
                });
            }

            // Join with OR operator
            searchPattern = patterns.join('|');

            // Use RegExp for the replacement
            const regex = new RegExp(searchPattern, inWhat.get() === "All" ? "g" : "");
            str = inputString.replace(regex, inRepl.get());
        }
        else { // No pipes or pipe handling disabled
            if (inUseRegex.get()) {
                // Use the pattern directly as regex
                const regex = new RegExp(searchPattern, inWhat.get() === "All" ? "g" : "");
                str = inputString.replace(regex, inRepl.get());
            } else {
                // Use simple string replacement
                if (inWhat.get() === "All") {
                    // Use split-join for global replacement without regex
                    str = inputString.split(searchPattern).join(inRepl.get());
                } else {
                    // Use standard replace for first occurrence
                    str = inputString.replace(searchPattern, inRepl.get());
                }
            }
        }
    }
    catch (e)
    {
        op.setUiError("exception", "exception " + e.message);
    }

    outStr.set(str);
}

// Helper function to escape special RegExp characters
function escapeRegExp(string) {
    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions