String replace


#1

Is there a better/simpler way to do this?
Can I write all the search and replace input in only one code block?


#2

Have a look at the result of selecting all the nodes and using the ‘Node to Code’ function in the right-click menu. The resulting design script might give you some ideas :wink:


#3

Thats not it.
What I want is one code block and one string replace node. If its possible?


#4

depending how many replacement pairs you have, you may want a dictionary
Yes, it is possible in one code block


#5

Thanks


#6

Personally I don’t like dictionaries for string replacement, as they tend to fall apart a bit due to the in-controllable nature of strings. Case in point if you were to look for the key “000110” you’d want to return “SK1,” but since there is no exact match for “000110” in the dictionary you receive null instead. This is not only not the intended result, but it introduces a change in data type as well. Simply put, with strings I feel that there are often too many wildcards to utilize dictionaries effectively.

So that puts me back to the drawing board. Instead of chaining all the nodes together you can call the entire string replacement chain in one code block as @Ewan_Opie indicated (with some added steps to clarify):

.

Even better, if you have an unknown number of replacement pairs, or you don’t want to spend forever coding each possible replacement, you could utilize a custom iterative function. By iterating over the list for every input pair it changes the value sequentially. This way it doesn’t matter how many replacement terms you have - in the end you’ll get what you’re after:

There are a few issues with replacing the same text twice (note the space before and after " be " in my first pair - this was required to not replace the ‘be’ in “better”), but this should get you started anyway.


How to create a "while" function
#7

For fun and a bit of python practice, I made a script that can replace a substring with another string and can handle most situations (as far as I can tell). Also gives a list of bools whether there was something replaced or not if needed.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
#The inputs to this node will be stored as a list in the IN variables.

def replacing(aString,replaceList,new,bools):
	count = 0
	if isinstance(rplce[0],list):
		for r in rplce:
			if aString.find(r[0]) != -1:
				h = aString.replace(r[0],r[1])
				new.append(h)
				count +=1
				bools.append(True)
			else:
				continue
	else:
		r = replaceList
		if aString.find(r[0]) != -1:
				h = aString.replace(r[0],r[1])
				new.append(h)
				count += 1
				bools.append(True)
	if count == 0:
		new.append(aString)
		bools.append(False)


strng = IN[0]
rplce = IN[1]
new = []
bools = []
if isinstance(strng,list):
	for s in strng:
		replacing(s,rplce,new,bools)
else:
	replacing(strng,rplce,new,bools)
OUT = new,bools

replaceStrings.dyn (10.9 KB)

The final node is the one in the bottom right that has the bool list showing.

Edit: Forgot about list of lists as inputs, so will be trying to make a recursive version as well.


#8

Now with recursion:
replaceStrings.dyn (3.5 KB)

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
#The inputs to this node will be stored as a list in the IN variables.

def replacing(aString,replaceList,new,bools):
	count = 0
	if isinstance(replaceList[0],list):
		for r in replaceList:
			if aString.find(r[0]) != -1:
				h = aString.replace(r[0],r[1])
				new.append(h)
				count +=1
				bools.append(True)
			else:
				continue
	else:
		r = replaceList
		if aString.find(r[0]) != -1:
				h = aString.replace(r[0],r[1])
				new.append(h)
				count += 1
				bools.append(True)
	if count == 0:
		new.append(aString)
		bools.append(False)

def recReplace(aString,aReplace,new,bools):
	if isinstance(aString,list):
	  temp = []
	  tempb = []
	  for i in aString:
	    recReplace(i,aReplace,temp,tempb)
	  new.append(temp)
	  bools.append(tempb)
	else:
	  replacing(aString,aReplace,new,bools)
		


strng = IN[0]
rplce = IN[1]
new = []
bools = []
recReplace(strng,rplce,new,bools)
OUT = new,bools

#9


I highly doubt the efficiency of this, but it works.
Edit: I’d like to write down the advantage of using this method, it’s very easy to add an element you’d want to replace, just add, to the list, in the case you’d want to automate the input it should work.


#10


I did a quick fix on my previous post as I realized that if you were in the case you’d give an input that shouldn’t get a replacement you’d end up with null outputs, which of course, you don’t want to happen.

I managed to give it a simple fix with Clockworks Liste.ReplaceNull nodes. You still get warnings, but they won’t cause actual problems.


#11

@moeng

I think you want something like this.


#12

Are you certain that actually replaces parts of strings?


#13

Ow my bad. You mean like replace the 1 in A1. If that’s te case give me a couple minuts.


#14

This will replace the substring