I had an interesting conversation (well, set of emails) with a reader today who had an interesting problem. Given an input string, he needed to remove some special characters and change spaces to underscores. He knew he could do it with a few Replace calls but wasn't sure if he could do it in one quick function call. I recommend replaceList. Let's look at an example of this and then I'll demonstrate what I found with null replacements.
First, let's take an initial string:
<cfset string = "This is $stuff with % things I don't like it.">
And then let's replace the special characters and spaces:
<!--- replace $ with nothing, % with nothing, and spaces with _ --->
<cfset clean = replace(string, "$", "", "all")>
<cfset clean = replace(clean, "%", "", "all")>
<cfset clean = replace(clean, " ", "_", "all")>
This returns: This_is_stuff_with__things_I_don't_like_it. That's perfect - but can we make the code a bit tighter? A reReplace would let me combine the first two calls into one - but let's look at how replaceList can do all three at once. replaceList is simple. Given an input string, take any found instance of the Nth item of a list with the Nth item of a second list. So for example: replaceList(string, "a,b,c", "1,2,3"). This implies that any "a" should be changed to a 1, any "b" with a 2, and any "c" with a 3.
So given that, let's try to combine our three replace calls with one list. The question is - how do you handle replacing $ and % with nothing? I tried using empty list elements like so:
<cfset clean = replaceList(string, "$,%, ", ",,_")>
But it produced: Thisis_stuffwiththingsIdon'tlikeit. Not exactly what I expected. It looks like it replaced all spaces and the % with nothing. The one $ character was replaced with an underscore. I'm guessing the logic was to ignore the empty list values in the second list and basically act as if I had done: replaceList(string, "$,%, ", "_"). Apparently replaceList automatically says, "if you ask me to replace items in list 1 and it's bigger than list 2, I'll treat the rest as being replaced with nothing."
So given that - if we change things up a bit, we should be ok:
<cfset clean = replaceList(string, " ,$,%", "_")>
Basically the idea is - start off with the things you want to have true replacements for - spaces and underscores. Then list the things you just want nuked after. This gives us: This_is_stuff_with__things_I_don't_like_it.
The last tip I had for the user - and I'd suggest this any time - was to turn the code above into a UDF. Yeah it's pretty darn short, but the logic is something you'll probably do in more than one place. Wrapping it into a quick UDF gives you an easy way to ensure you can change the logic later on.
Archived Comments
How about using a regular expression:
<cfset clean=reReplace(string, "[\$% ]+", "_", "ALL")>
The result would be: "This_is_stuff_with_things_I_don't_like_it."
As long as it's ok when subsequent spaces get stripped to one underline the solution i'd recommend.
Regards, Cyrill
But the point was - he had different replacement rules. $ and % were removed, but spaces became underlines.
Ray, interesting quandary I'm facing with this solution; the replacement works well but, I wanted to nuke double and single quotes too. I created a test page that pulled some data from the DB for me to work with. In Firebug I could see quotes in the SRC attribute so I put \"" in my search pattern to nuke the double quotes. Didn't work. I looked directly at the data and noticed the data showed &quo... What the heck?
The trouble was that I am running htmlEditFormat() on my data as it goes into the DB. Weird that firebug would show it as " on the screen and not &quo...
Now I'm placing &quo to my search string to nuke it as well.
ofeargall - if you don't want to do multiple replaces, you should be able to use CHR(39) and CHR(34) (I think that's ' and "). I've used that to strip out newlines and so on, so I expect it will work for quotes as well
I've never run across the behavior Ray notes and I've used it a lot, but maybe I've just always put the stuff I'm replacing before the stuff I'm stripping because that seems the logical way to do it.
Ray, didn't Adobe change the behavior of empty list values in 8 or 9? I seem to recall something about it, but I forget if I got hit by it or just saw it as a curiousity while researching something else (we're still on CF8).
JC - I believe only arrayToList was updated to support null items. That's all that needed to be updated really. Do the conversion there once if you care about null items and then work with the array.
Working on one Code Found there is nothing like ReplaceListNoCase and in my case, it was actually not matching what i have specified in my list1
so i worked it like this and it worked:
ReplaceList(lcase(arguments.sta),'rejected,locked,on-hold','1,2,3')>
Coldfusion 10 onwards
Thanks! So much easier to get my head around than https://cfdocs.org/replacelist