Operator Type:
Operator Scope of Action:
Operator Purpose:
Operator First Added:
Operator Altered:
Function [other Function type actions]
Item [operators of similar scope]
Data manipulation [other Data manipulation operators]
Baseline
List.replace("match","replacement")
This operator allows simple text transformations without use of runCommand as was hitherto required; the result remains a List or Set as per the list of references supplied. Unlike in contains() type operators, some regex patterns are not supported for either argument; regex use is discussed in more detail below.
match and replacement are both one of:
- an action code expression (which includes just referencing a single attribute name')
- a quoted literal string (i.e. actual text)
$MyList.replace("match","replacement")
List and set type attributes can use replace, though the scope of replacement is more limited than with strings. With listings, the match with and replacement of can only be for a complete list value and not part of a value.
Using regex
Most basic regex expressions should work but string start (^) and string end ($) matches work in an unexpected way. When .replace() is run it looks at the internal string value of the Set or List.
Thus a list of values, like ant/bee/cow/dog/eel, is stored and matched as a single semi-colon delimited string "ant;bee;cow;dog;eel
". Note Tinderbox does not create a final semi-colon after the last value, but won't complain if the user adds one, e.g. via manual input. Thus the ^ regex pattern matches only before the 'a' of 'ant' and not the start of other list values. Similarly, $ matches after the 'g' of dog and not the end of other list values. It might be thought of as '^ant;bee;cow;dog;eel$' as opposed to '^ant$;^bee$;^cow$;^dog$;^eel$'.
So, in-list value boundaries still exist for regex matching but only as literal semicolons. Thus to change 'ee' to 'eet' in the above list but only for 'bee' and not 'eel':
$MyListA = $MyList.replace("ee;","eet;").replace("ee$","eet")
Note how two chained .replace() calls are needed, not one. The first is for inter-value boundaries and the second for the overall string end (had the data had a closing semi-colon the first match catches it so that scenario's still covered. To reverse the scenario and match the 'ee' at the start of a value:
$MyListA = $MyList.replace(";ee","ree;").replace("^ee","ree")
That changes 'eel' to 'reel' but leaves 'bee' unaltered.
It is possible to write back to the same attribute:
$MyList = $MyList.replace("ee;","eet;").replace("ee$","eet")
but, the former is a good idea whilst developing/testing code for this technique, only switching out latter once sure of the result.
Trimming leading/trailing whitespace
$MyList = $MyList.replace("+","").replace(" +$","").replace(" *; *",";")
The ' +' means one or more space characters. The first replace finds such a sub-string immediately following the start of the whole string ^), whilst the second does the same for a sub-string immediately before the end of the string ($). The third replace finds zero or more space characters either side of a semi-colon (the per-item list delimiter). The latter also matches a normal ';' delimiter but the test save writing separate regexs for space before and after the delimiter (e.g. " +;" and "; +") so the zero-or-more test (*) is used here instead of the one-or-more (+) used for the start/end of the overall string. Thus, using the code above, a lists like these with items having undesired leading/trailing space:
" ant ; bee ; cow ; dog "
" ant ;bee ;cow ; dog"
…become…
"ant;bee;cow;dog"
Dealing with inline quote characters
Because pattern is parsed for regular expressions, it may be possible to use the '\dnn' form described here to work around the lack of escaping from single double quotes within strings.