REPLACESTRINGS

=REPLACESTRINGS(searchTxt, findList, replaceList)

searchTxt
a single string of text
findList
an array of strings to find in searchTxt
replaceList
an array of strings to replace corresponding entries from findList

REPLACESTRINGS bulk replaces matched substrings from one list with corresponding entries in a 2nd list.

tboulden

Board Regular
Joined
Jan 14, 2021
Messages
73
Office Version
  1. 365
Platform
  1. Windows
REPLACESTRINGS bulk replaces matched substrings from one list with corresponding entries in a 2nd list.

If lists are not same length, only makes replacements up to the last entry in the shortest list. Function works recursively and returns the final string with all replacements.

Excel Formula:
=LAMBDA(
    searchTxt,
    findList,
    replaceList,
    LET(
        n,
        MIN(
            ROWS(findList),
            ROWS(replaceList)
        ),
        Loop,
        LAMBDA(
            ME,
            myTxt,
            i,
            LET(
                find,INDEX(findList,i),
                rep,INDEX(replaceList,i),
                new,SUBSTITUTE(myTxt,find,rep),
                IF(
                    i<n,ME(ME,new,i+1),
                    new
                )
            )
        ),
        Loop(Loop,searchTxt,1)
    )
)

LAMBDA_Testing_ReplaceStrings.xlsm
BCDEFGHI
2Input:This is a test
3
4Input ListsModeled Behavior
5FindReplaceTextiFindReplaceReturn
6ThisThatThis is a test1ThisThatThat is a test
7isISThat is a test2isISThat IS a test
8aanThat IS a test3aanThant IS an test
9testexampleThant IS an test4testexampleThant IS an example
10
11Anonymous:Thant IS an example
12Named:Thant IS an example
Scratch
Cell Formulas
RangeFormula
E6E6=C2
G6:G9G6=INDEX($B$6:$B$9,F6)
H6:H9H6=INDEX($C$6:$C$9,F6)
I6:I9I6=SUBSTITUTE(E6,G6,H6)
E7:E9E7=I6
F7:F9F7=F6+1
C11C11=LAMBDA(searchTxt,findList,replaceList,LET(n,MIN(ROWS(findList),ROWS(replaceList)),Loop,LAMBDA(ME,myTxt,i,LET(find,INDEX(findList,i),rep,INDEX(replaceList,i),new,SUBSTITUTE(myTxt,find,rep),IF(i<n,ME(ME,new,i+1),new))),Loop(Loop,searchTxt,1)))(C2,B6:B9,C6:C9)
C12C12=ReplaceStrings(C2,B6:B9,C6:C9)
 
Last edited by a moderator:
Upvote 1
Beautiful implementation of a Loop by using LET, and also using the ME concept for recursion instead of only for testing a Lambda function without creating the named range!

Thanks for sharing this.


I would like to suggest one thing unrelated to the function but providing a sample with XL2BB. Please try to start from cell A1 instead of cell B2 (or another random cell) as much as possible. Honestly, it confused me when I copied & pasted it in a worksheet since the formulas are still using the references of how they were created in the sample mini-sheet, therefore all I get is an error at the first copy & paste attempt. I mostly check the top-left cell reference when I copy a mini-sheet from the board, and it might not be a big deal starting from B2, however, it gets really hard when it starts from DQ3.

Again, beautiful implementation!
 
Beautiful implementation of a Loop by using LET, and also using the ME concept for recursion instead of only for testing a Lambda function without creating the named range!
Thanks!
I would like to suggest one thing unrelated to the function but providing a sample with XL2BB. Please try to start from cell A1 instead of cell B2 (or another random cell) as much as possible. Honestly, it confused me when I copied & pasted it in a worksheet since the formulas are still using the references of how they were created in the sample mini-sheet, therefore all I get is an error at the first copy & paste attempt. I mostly check the top-left cell reference when I copy a mini-sheet from the board, and it might not be a big deal starting from B2, however, it gets really hard when it starts from DQ3.
Ahh, I see, this isn't an annoyance that had occurred to me, but I will make a point to keep close to A1 in the future!
 
And with some inspiration from Dave Bruns' latest, here's a non-recursive version. Note that I think this could be LET-only if you replace the STARTPOS and LIST.COMBINE references appropriately. A notable difference is that this version requires a delimiter to split searchTxt on; this could probably be eliminated, but I think it would be more complicated than trying to do the same thing with the recursive version.

Excel Formula:
=LAMBDA(
    searchTxt,
    delimiter,
    findList,
    replaceList,
    LET(
        delPositions,StartPos(searchTxt,delimiter,"ALL"),
        splitPositions,
            List.Combine(
                List.Combine(1,delPositions),
                LEN(searchTxt)+1
            ),
        rowCt,ROWS(splitPositions),
        startPositions,INDEX(splitPositions,SEQUENCE(rowCt-1)),
        endPositions,INDEX(splitPositions,SEQUENCE(rowCt-1,1,2)),
        chunks,
            MID(
                searchTxt,
                startPositions,
                endPositions-startPositions
            ),
        subDel,SUBSTITUTE(chunks,delimiter,""),
        findIndices,MATCH(subDel,findList,0),
        finds,INDEX(findList,findIndices),
        repls,INDEX(replaceList,findIndices),
        replace,
            IF(
                ISERROR(
                    INDEX(
                        finds,
                        SEQUENCE(rowCt-1)
                    )
                ),
                subDel,
                repls
            ),
        join,TEXTJOIN(delimiter,TRUE,replace),
        join
    )
)
LAMBDA_Testing_ReplaceStrings.xlsm
ABCDE
1Anonymous:The black dog sat on #@! grass
2
3
4Textfindreplace
5The white dog sat on green grassThe black dog sat on #@! grassredugly
6He wore a warm gray sweaterHe wore a warm gray sweaterblue123
7The sun set red on the blue horizonThe sun set ugly on the 123 horizonwhiteblack
8There were pink neon signs everywhereThere were pinkish neon signs everywherepinkpinkish
9The waves where a deep blue colorThe waves where a deep 123 colorgreen#@!
10She was wearing hot pink socksShe was wearing hot pinkish socks
11Her eyes were blue and greenHer eyes were 123 and #@!
12The basket held one green sockThe basket held one #@! sock
13The brown belt was simply missingThe brown belt was simply missing
14A white banner with blue and red textA black banner with 123 and ugly text
15Red, white, and blueRed, white, and 123
ContainsWhichThings
Cell Formulas
RangeFormula
B1B1=LAMBDA(searchTxt,delimiter,findList,replaceList,LET(delPositions,StartPos(searchTxt,delimiter,"ALL"),splitPositions,List.Combine(List.Combine(1,delPositions),LEN(searchTxt)+1),rowCt,ROWS(splitPositions),startPositions,INDEX(splitPositions,SEQUENCE(rowCt-1)),endPositions,INDEX(splitPositions,SEQUENCE(rowCt-1,1,2)),chunks,MID(searchTxt,startPositions,endPositions-startPositions),subDel,SUBSTITUTE(chunks,delimiter,""),findIndices,MATCH(subDel,findList,0),finds,INDEX(findList,findIndices),repls,INDEX(replaceList,findIndices),replace,IF(ISERROR(INDEX(finds,SEQUENCE(rowCt-1))),subDel,repls),join,TEXTJOIN(delimiter,TRUE,replace),join))(A5," ",things,replace)
B5:B15B5=ReplaceStrings(A5," ",things,replace)
Named Ranges
NameRefers ToCells
replace=ContainsWhichThings!$E$5:$E$9B1, B5:B15
things=ContainsWhichThings!$D$5:$D$9B1, B5:B15
 
this could probably be eliminated, but I think it would be more complicated than trying to do the same thing with the recursive version.
And I can't leave my own challenge unaccepted, here's the non-recursive version of the original.

Excel Formula:
=LAMBDA(
    searchTxt,
    findList,
    replaceList,
    LET(
        findsInTxt,FIND(findList,searchTxt),
        findBools,ISNUMBER(findsInTxt),
        initFinds,FILTER(findList,findBools,""),
        findStartPositions,FILTER(findsInTxt,NOT(ISERROR(findsInTxt)),""),
        findEndPositions,findStartPositions+LEN(initFinds),
        findSplitPositions,
            SORT(
                List.Combine(findStartPositions,findEndPositions)
            ),
        splitPositions,
            List.Combine(
                List.Combine(1,findSplitPositions),
                LEN(searchTxt)+1
            ),
        rowCt,ROWS(splitPositions),
        startPositions,INDEX(splitPositions,SEQUENCE(rowCt-1)),
        endPositions,INDEX(splitPositions,SEQUENCE(rowCt-1,1,2)),
        chunks,
            MID(
                searchTxt,
                startPositions,
                endPositions-startPositions
            ),
        findIndices,MATCH(chunks,findList,0),
        finds,INDEX(findList,findIndices),
        repls,INDEX(replaceList,findIndices),
        replace,
            IF(
                ISERROR(
                    INDEX(
                        finds,
                        SEQUENCE(rowCt-1)
                    )
                ),
                chunks,
                repls
            ),
        join,IFERROR(TEXTJOIN("",TRUE,replace),searchTxt),
        join
    )
)

LAMBDA_Testing_ReplaceStrings.xlsm
ABCDEF
1Anonymous:The black dog sat on #@! grass
2
3
4TextLET-based, non-recursiveRecurisvefindreplace
5The white dog sat on green grassThe black dog sat on #@! grassThe black dog sat on #@! grassredugly
6He wore a warm gray sweaterHe wore a warm gray sweaterHe wore a warm gray sweaterblue123
7The sun set red on the blue horizonThe sun set ugly on the 123 horizonThe sun set ugly on the 123 horizonwhiteblack
8There were pink neon signs everywhereThere were pinkish neon signs everywhereThere were pinkish neon signs everywherepinkpinkish
9The waves where a deep blue colorThe waves where a deep 123 colorThe waves where a deep 123 colorgreen#@!
10She was wearing hot pink socksShe was wearing hot pinkish socksShe was wearing hot pinkish socks
11Her eyes were blue and greenHer eyes were 123 and #@!Her eyes were 123 and #@!
12The basket held one green sockThe basket held one #@! sockThe basket held one #@! sock
13The brown belt was simply missingThe brown belt was simply missingThe brown belt was simply missing
14A white banner with blue and red textA black banner with 123 and ugly textA black banner with 123 and ugly text
15Red, white, and blueRed, black, and 123Red, black, and 123
16
17LET-based, non-recursive, delimiter
18The black dog sat on #@! grass
19He wore a warm gray sweater
20The sun set ugly on the 123 horizon
21There were pinkish neon signs everywhere
22The waves where a deep 123 color
23She was wearing hot pinkish socks
24Her eyes were 123 and #@!
25The basket held one #@! sock
26The brown belt was simply missing
27A black banner with 123 and ugly text
28Red, white, and 123
ContainsWhichThings
Cell Formulas
RangeFormula
B1B1=LAMBDA(searchTxt,findList,replaceList, LET( findsInTxt,FIND(findList,searchTxt), findBools,ISNUMBER(findsInTxt), initFinds,FILTER(findList,findBools,""), findStartPositions,FILTER(findsInTxt,NOT(ISERROR(findsInTxt)),""), findEndPositions,findStartPositions+LEN(initFinds), findSplitPositions, SORT( List.Combine(findStartPositions,findEndPositions) ), splitPositions, List.Combine( List.Combine(1,findSplitPositions), LEN(searchTxt)+1 ), rowCt,ROWS(splitPositions), startPositions,INDEX(splitPositions,SEQUENCE(rowCt-1)), endPositions,INDEX(splitPositions,SEQUENCE(rowCt-1,1,2)), chunks, MID( searchTxt, startPositions, endPositions-startPositions ), findIndices,MATCH(chunks,findList,0), finds,INDEX(findList,findIndices), repls,INDEX(replaceList,findIndices), replace, IF( ISERROR( INDEX( finds, SEQUENCE(rowCt-1) ) ), chunks, repls ), join,IFERROR(TEXTJOIN("",TRUE,replace),searchTxt), join ) )(A5,things,replace)
B5:B15B5=ReplaceStrings(A5,things,replace)
C5:C15C5=ReplaceStrings.Loop(A5,things,replace)
B18:B28B18=ReplaceStrings.Delimiter(A5," ",things,replace)
Named Ranges
NameRefers ToCells
replace=ContainsWhichThings!$F$5:$F$9B1, B5:C15, B18:B28
things=ContainsWhichThings!$E$5:$E$9B1, B5:C15, B18:B28
 
Impresive work !! Wrote a recursive lambda that can handle the whole string column array
RPLAB(ar,a,b,i)=LAMBDA(ar,a,b,i,LET(r,ROWS(a),IF(i=r+1,ar,RPLAB(SUBSTITUTE(ar,INDEX(a,i),INDEX(b,i)),a,b,i+1))))
-replace a with b for array ar and i=1
If you don't like extra variable i we write another one REPLACEAB(ar,a,b)=LAMBDA(ar,a,b,RPLAB(ar,a,b,1))
Anyhow "i" can be very handy in case you want to change the index in the replace list. For ex. i=2 will ignore changing red with ugly.
Also the repl lists should be appended with PROPER variants if we want to replace the words that start with capital letters.✌
 

Forum statistics

Threads
1,223,908
Messages
6,175,305
Members
452,633
Latest member
DougMo

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top