How to replace multiple strings in a list with sublists?
I am trying to replace a list composed of 8 strings if they are contaned into a list of many sublists of strings. I found useful the clockwork package node Replace.Multiple but I would like to do it with designscript or python.
it works sometimes…but the custom node takes quite a lot time to replace strings, then looking for alternative
this example does not work, I thought it does not work with Empt Lists and Nulls but it works within a custom node package…so I guess it does not work with a list of sublists strings as input
the code:
import clr
import re
def ReplaceMultiple(str, searchstr, replacestr, sort):
replacements = dict(zip(searchstr, replacestr))
if sort: substrs = sorted(replacements, key=len, reverse=True)
else: substrs = searchstr
regexp = re.compile('|'.join(map(re.escape, substrs)))
return regexp.sub(lambda match: replacements[match.group(0)], str)
if isinstance(IN[1], list): searchstr = IN[1]
else: searchstr = [IN[1]]
if isinstance(IN[2], list): replacestr = IN[2]
else: replacestr = [IN[2]]
if isinstance(IN[0], list): OUT = [ReplaceMultiple(x, searchstr, replacestr, False) for x in IN[0]]
else: OUT = ReplaceMultiple(IN[0], searchstr, replacestr, False)
// Search the texts
texts: string[][];
// Search pattern that must be replaced
searchtexts: string[];
// Replace pattern
replacetexts: string[];
// Function to replace multiple texts
[Imperative]
{
result = [];
// Loop through all texts
for (i in 0..List.Count(texts)-1)
{
currenttext = texts[i];
// Loop through the search patterns that must be replaced
for (j in 0..List.Count(searchtexts)-1)
{
currenttext = String.Replace(currenttext, searchtexts[j], replacetexts[j]);
}
// Add it to the result
result[i] = currenttext;
}
return result;
};
I agree. @ruben.romero, what you’re asking is probably perfectly possible but we can’t really figure out what you’re trying to achieve like this. Can you just show an example of what your input list looks like and what you want your output list to look like?
import sys
import clr
import re
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
def replacetext(text):
global dict_replace
if text is not None:
rep = dict((re.escape(k), v) for k, v in dict_replace.items())
pattern = re.compile("|".join(rep.keys()))
text = pattern.sub(lambda m: rep[re.escape(m.group(0))], text)
return text
def nestedRecursFunc(lst, functoApply):
newlst = list(lst)[:] # copy input list and convert it (if necessary)
for idx, elem in enumerate(lst):
if isinstance(elem, list) and len(elem) > 0:
newlst[idx] = nestedRecursFunc(lst[idx], functoApply)
elif isinstance(elem, list) and len(elem) == 0:
newlst[idx] = []
else:
newlst[idx] = functoApply(lst[idx])
return newlst
multi_NestedList = IN[0]
dict_replace = dict(IN[1])
OUT = nestedRecursFunc(multi_NestedList, replacetext)
@PauLtus something like this, @Anton_Huizinga I tried python and designscript, and the python of custom node was double faster with many items in the string list input
subs = IN[0]
searchStr = IN[1]
replaceStr = IN[2]
out = []
for sub in subs:
output = []
for s in sub:
for search,replace in zip(searchStr,replaceStr):
s = s.replace(search,replace)
output.append(s)
out.append(output)
OUT = out
Your list structure is kinda weird, if it’s always like this, it’s okay but if you want that to work consistently it might actually be the easiest to string together a bunch of String.Replace nodes.
Anyway, a bit of Python is still more elegant so here we go:
txtlist = IN[0]
oldlist = IN[1]
replist = IN[2]
outlist=[]
for txt1 in txtlist:
out = []
for txt in txt1:
for old,rep in zip(oldlist,replist):
txt.replace(old,rep)
out.append(txt)
outlist.append(out)
OUT = outlist
Edit: @Nick_Boyts had the exact same idea, it seems.
many thanks @Nick_Boyts@Anton_Huizinga@PauLtus@c.poupin , I also tried that code which I found in other forum posts before write my post initially and I remember to have a warning message in the python node. Now I tried and it works fine, I did a comparison between the solution with Designscript as well and you can check run time results, Python wins.
thanks great answers to everyone, but disappointed with the python I wrote even looking smart and the @c.poupin version as well.
hello, in advance sorry for the digression
Depending on what you “claim”, it is more efficient to switch to Python as soon as you have loops rather than stay in Designscript,
where it was humorous (note for jokes.)