using multiple characters as delimiters in Coldfusion list - coldfusion

I am trying to use multiple characters as the delimeter in ColdFusion list like ,( comma and blank) but it ignores the blank.
I then tried to use:
<cfset title = listappend( title, a[ idx ].title, "#Chr(44)##Chr(32)#" ) />
But it also ignores the blank and without blanks the list items to diffucult to read.
Any ideas?

With ListAppend you can only use one delimiter. As the docs say for the delimiters parameter:
If this parameter contains more than one character, ColdFusion uses only the first character.
I'm not sure what a[ idx ].title contains or exactly what the expected result is (would be better if you gave a complete example), but I think something like this will do what you want or at least get you started:
<cfscript>
a = [
{"title"="One"},
{"title"="Two"},
{"title"="Three"}
];
result = "";
for (el in a) {
result &= el.title & ", ";
}
writeDump(result);
</cfscript>

I think there's a fundamental flaw in your approach here. The list delimiter is part of the structure of the data, whereas you are also trying to use it for "decoration" when you come to output the data from the list. Whilst often conveniently this'll work, it's kinda conflating two ideas.
What you should do is eschew the use of lists as a data structure completely, as they're a bit crap. Use an array for storing the data, and then deal with rendering it as a separate issue: write a render function which puts whatever separator you want in your display between each element.
function displayArrayAsList(array, separator){
var list = "";
for (var element in array){
list &= (len(list) ? separator : "");
list &= element;
}
return list;
}
writeOutput(displayAsList(["tahi", "rua", "toru", "wha"], ", "));
tahi, rua, toru, wha

Use a two step process. Step 1 - create your comma delimited list. Step 2
yourList = replace(yourList, ",", ", ", "all");

Related

Can I split a column text as array using data factory data flow?

Inside my data flow pipeline I would like to add a derived column and its datatype is array. I would like to split the existing column with 1000 characters without breaking words. I think we can use regexSplit,
regexSplit(<string to split> : string, <regex expression> : string) => array
But I do not know which regular expression I can use for split the existing column without breaking words.
Please help me to figure it out.
I created a workaround for this and it works fine for me.
filter(split(regexReplace(regexReplace(text, `[\t\n\r]`, ``), `(.{1,1000})(?:\s|$)`, `$1~~`), '~~'), #item !="")
I think, we have a better solution than this.
I wouldn't use a regex for this, but a truncating function like this one, courtesy of TimS:
public static string TruncateAtWord(this string input, int length)
{
if (input == null || input.Length < length)
return input;
int iNextSpace = input.LastIndexOf(" ", length, StringComparison.Ordinal);
return string.Format("{0}…", input.Substring(0, (iNextSpace > 0) ? iNextSpace : length).Trim());
}
Translated into expression functions it would look something* like this.
substring(Input, 1, iif(locate(Input, ' ', 1000) > 0, locate(Input, ' ', 1000) , length(Input)) )
Since you don't have a lastIndexOf available as an expression function, you would have to default to locate, which means that this expression truncates the string at the first space after the 1000th character.
*I don't have an environment where I can test this.

how can I linebreak javascript with regex keeping sperator

what I wanna do is
change
1.apple2.cat3.green(1)table(2)computer①what②can i③do?●help●me●plz
this to
1.apple
2.cat
3.green
(1)table
(2)computer
①what
②can i
③do?
●help
●me
●plz
this
there're many kind of delimiter
"1.", "2." .. "(1)".."(2)"..■ ○
and so on
number is only a single digit
I want to list many delimiter can split or add linebreak, but keep delimiter
number or bullet should not be deleted.
You can use regex like below:
let s = '1.apple2.cat3.green(1)table(2)computer①what②can i③do?●help●me●plz';
let regex = /(\d\.|\(\d\)|[①-⑳]|●|■|○)[a-z]+/ig;
let result = null;
while (result = regex.exec(s)) {
console.log(result[0]); // or you can push into an array, etc.
}

Allow user to pass a separator character by doubling it in C++

I have a C++ function that accepts strings in below format:
<WORD>: [VALUE]; <ANOTHER WORD>: [VALUE]; ...
This is the function:
std::wstring ExtractSubStringFromString(const std::wstring String, const std::wstring SubString) {
std::wstring S = std::wstring(String), SS = std::wstring(SubString), NS;
size_t ColonCount = NULL, SeparatorCount = NULL; WCHAR Separator = L';';
ColonCount = std::count(S.begin(), S.end(), L':');
SeparatorCount = std::count(S.begin(), S.end(), Separator);
if ((SS.find(Separator) != std::wstring::npos) || (SeparatorCount > ColonCount))
{
// SEPARATOR NEED TO BE ESCAPED, BUT DON'T KNOW TO DO THIS.
}
if (S.find(SS) != std::wstring::npos)
{
NS = S.substr(S.find(SS) + SS.length() + 1);
if (NS.find(Separator) != std::wstring::npos) { NS = NS.substr(NULL, NS.find(Separator)); }
if (NS[NS.length() - 1] == L']') { NS.pop_back(); }
return NS;
}
return L"";
}
Above function correctly outputs MANGO if I use it like:
ExtractSubStringFromString(L"[VALUE: MANGO; DATA: NOTHING]", L"VALUE")
However, if I have two escape separators in following string, I tried doubling like ;;, but I am still getting MANGO instead ;MANGO;:
ExtractSubStringFromString(L"[VALUE: ;;MANGO;;; DATA: NOTHING]", L"VALUE")
Here, value assigner is colon and separator is semicolon. I want to allow users to pass colons and semicolons to my function by doubling extra ones. Just like we escape double quotes, single quotes and many others in many scripting languages and programming languages, also in parameters in many commands of programs.
I thought hard but couldn't even think a way to do it. Can anyone please help me on this situation?
Thanks in advance.
You should search in the string for ;; and replace it with either a temporary filler char or string which can later be referenced and replaced with the value.
So basically:
1) Search through the string and replace all instances of ;; with \tempFill- It would be best to pick a combination of characters that would be highly unlikely to be in the original string.
2) Parse the string
3) Replace all instances of \tempFill with ;
Note: It would be wise to run an assert on your string to ensure that your \tempFill (or whatever you choose as the filler) is not in the original string to prevent an bug/fault/error. You could use a character such as a \n and make sure there are non in the original string.
Disclaimer:
I can almost guarantee there are cleaner and more efficient ways to do this but this is the simplest way to do it.
First as the substring does not need to be splitted I assume that it does not need to b pre-processed to filter escaped separators.
Then on the main string, the simplest way IMHO is to filter the escaped separators when you search them in the string. Pseudo code (assuming the enclosing [] have been removed):
last_index = begin_of_string
index_of_current_substring = begin_of_string
loop: search a separator starting at last index - if not found exit loop
ok: found one at ix
if char at ix+1 is a separator (meaning with have an escaped separator
remove character at ix from string by copying all characters after it one step to the left
last_index = ix+1
continue loop
else this is a true separator
search a column in [ index_of_current_substring, ix [
if not found: error incorrect string
say found at c
compare key_string with string[index_of_current_substring, c [
if equal - ok we found the key
value is string[ c+2 (skip a space after the colum), ix [
return value - search is finished
else - it is not our key, just continue searching
index_of_current_substring = ix+1
last_index = index_of_current_substring
continue loop
It should now be easy to convert that to C++

Dynamic regexprep in MATLAB

I have the following strings in a long string:
a=b=c=d;
a=b;
a=b=c=d=e=f;
I want to first search for above mentioned pattern (X=Y=...=Z) and then output like the following for each of the above mentioned strings:
a=d;
b=d;
c=d;
a=b;
a=f;
b=f;
c=f;
d=f;
e=f;
In general, I want all the variables to have an equal sign with the last variable on the extreme right of the string. Is there a way I can do it using regexprep in MATLAB. I am able to do it for a fixed length string, but for variable length, I have no idea how to achieve this. Any help is appreciated.
My attempt for the case of two equal signs is as follows:
funstr = regexprep(funstr, '([^;])+\s*=\s*+(\w+)+\s*=\s*([^;])+;', '$1 = $3; \n $2 = $3;\n');
Not a regexp but if you stick to Matlab you can make use of the cellfun function to avoid loop:
str = 'a=b=c=d=e=f;' ; %// input string
list = strsplit(str,'=') ;
strout = cellfun( #(a) [a,'=',list{end}] , list(1:end-1), 'uni', 0).' %'// Horchler simplification of the previous solution below
%// this does the same than above but more convoluted
%// strout = cellfun( #(a,b) cat(2,a,'=',b) , list(1:end-1) , repmat(list(end),1,length(list)-1) , 'uni',0 ).'
Will give you:
strout =
'a=f;'
'b=f;'
'c=f;'
'd=f;'
'e=f;'
Note: As Horchler rightly pointed out in comment, although the cellfun instruction allows to compact your code, it is just a disguised loop. Moreover, since it runs on cell, it is notoriously slow. You won't see the difference on such simple inputs, but keep this use when super performances are not a major concern.
Now if you like regex you must like black magic code. If all your strings are in a cell array from the start, there is a way to (over)abuse of the cellfun capabilities to obscure your code do it all in one line.
Consider:
strlist = {
'a=b=c=d;'
'a=b;'
'a=b=c=d=e=f;'
};
Then you can have all your substring with:
strout = cellfun( #(s)cellfun(#(a,b)cat(2,a,'=',b),s(1:end-1),repmat(s(end),1,length(s)-1),'uni',0).' , cellfun(#(s) strsplit(s,'=') , strlist , 'uni',0 ) ,'uni',0)
>> strout{:}
ans =
'a=d;'
'b=d;'
'c=d;'
ans =
'a=b;'
ans =
'a=f;'
'b=f;'
'c=f;'
'd=f;'
'e=f;'
This gives you a 3x1 cell array. One cell for each group of substring. If you want to concatenate them all then simply: strall = cat(2,strout{:});
I haven't had much experience w/ Matlab; but your problem can be solved by a simple string split function.
[parts, m] = strsplit( funstr, {' ', '='}, 'CollapseDelimiters', true )
Now, store the last part of parts; and iterate over parts until that:
len = length( parts )
for i = 1:len-1
print( strcat(parts(i), ' = ', parts(len)) )
end
I do not know what exactly is the print function in matlab. You can update that accordingly.
There isn't a single Regex that you can write that will cover all the cases. As posted on this answer:
https://stackoverflow.com/a/5019658/3393095
However, you have a few alternatives to achieve your final result:
You can get all the values in the line with regexp, pick the last value, then use a for loop iterating throughout the other values to generate the output. The regex to get the values would be this:
matchStr = regexp(str,'([^=;\s]*)','match')
If you want to use regexprep at any means, you should write a pattern generator and a replace expression generator, based on number of '=' in the input string, and pass these as parameters of your regexprep func.
You can forget about Regex and Split the input to generate the output looping throughout the values (similarly to alternative #1) .

using a replace in coldfusion leaving trailing comma

I have a code where the values are coming as:
a,b,c from database..
now i want to remove c from the string based upon condition, c can be at any place, 1st, last or middle.
i am using replace to do it like this:
<cfset answer = Replace('a,b,c','c','','all')>
This works but it leaves a trailing comma at the end or at the start or 2 commas in middle breaking the whole string, what can be my approach here
<cfscript>
input = 'a,b,c';
foundAt = listFind(input, 'c');
answer = foundAt ? listDeleteAt(input, foundAt) : input;
writeOutput(answer);
</cfscript>
Run this code LIVE on TryCF.com
See: List functions
OR use REReplace(). The solution was just one google search away: Regex for removing an item from a comma-separated string?
function listRemoveAll(list, item) {
return REReplace(list, "\b#item#\b,|,\b#item#\b$", "", "all");
}