Option 1: Use a CF list function that supports multi-character delimiters, like listToArray.
<cfscript>
// split on first delimiter get "name->value" string
nameValuePairs = test.listToArray("~)|~" , false, true);
columnValues = [];
nameValuePairs.each(function(pair, index) {
// split on second delimiter to extract value
local.data = pair.listToArray("~|(~", false, true);
columnValues.append( local.data[ 2 ] );
});
writeDump( "Result 1: "& columnValues.toList() );
</cfscript>
Option 2: If you can identify a single character that's never present within the values, perhaps a non-printable character, just replace the existing delimiters, and loop as usual.
<cfscript>
// 31 == Unit separator
delim = chr(31);
newString = test.replace( "~)|~", delim, "all")
.replace( "~|(~", delim, "all");
columnValues = [];
newString.listToArray( delim ).each(function( elem, index) {
if (index mod 2 == 0) {
columnValues.append( elem );
}
});
WriteOutput( "<br>Result 2: "& columnValues.toList() );
</cfscript>
TryCF Examples
Update
problem though for this string supp~|(~lier_isd ~|(~ '3422' ~)|~supplier_name ~|(~ 'WD Ltd.' ~)|~project_personnel ~|(~ 'Yaya Toure (temp)' ~)|~lt_project_code ~|(~ '013-7718321' ~)|~ id ~|(~ '668' I was expecting lier_isd ~|(~ '3422', 'WD Ltd.', 'Yaya Toure (temp)', '013-7718321'
The initial string appeared to use the format name ~|(~ value ~)|~. However, if the value itself can contain one of the list delimiters ~|(~, you won't be able to use list functions, because the function can't differentiate between when ~|(~ is acting as a delimiter and when it's part of a value. You'll need to use a regex instead. That's not my forte, but something like this should work
TryCF Example
values = [];
// Find groups of "~|(~ value ~)|~"
matches = reMatch( "~\|\(~(.+?)(?=~\)\|~)", test);
matches.each( function(item, index) {
// remove text up to and including the first "~|(~"
local.str = reReplace( item, ".*?~\|\(~", "");
values.append( local.str );
});
WriteOutput( "Result 1: "& values.toList() );
Explanation
~ Find tilde "~"
\| Find pipe "|"
\( Find open parenthesis "("
~ Find tilde "~"
(.+?) One ore more characters, non-greedy
(?= Followed by (Non-capturing lookahead)
~ tilde "~"
\) close parenthesis "("
\| pipe "|"
~ tilde "~"
) End lookahead
.*? Zero or more characters
~ Find tilde "~"
\| Find pipe "|"
\( Find open parenthesis "("
~ Find tilde "~"