I was able to boil it down to a single loop, but still there is a copy call as well as three stringReplace calls.
function commaReplace(s:string):string;
var i:integer;
inString:boolean;
s2, d, dStr:string;
begin
//replace each comma within double quotes with semicolon, and then remove double quotes
//so we can use MySQL LOAD DATA function to load the .csv directly
//first remove dual double quotes
s:=stringReplace(s,'""','',[rfReplaceAll]);
inString:=false;
for i:=1 to length(s) do
begin
if s[i]='"' then
inString:=not inString
else
if inString and (s[i]=',') then
s[i]:=';';
if ((length(s)-i)>10) and (not inString) then
begin
d:=copy(s, i, 10);
if regEx.IsMatch(d) then
begin
//we have a date, change format from american mm/dd/yyyy to yyyy-mm-dd format
dStr:=copy(d, 7, 4)+'-'+copy(d, 1, 2)+'-'+copy(d, 4, 2);
//insert it in the right place
s:=copy(s, 1, i-1)+dStr+copy(s, i+10, length(s));
end;
end;
end;
s2:=stringReplace(s,'"','',[rfReplaceAll]);
//convert boolean Y to 1 in the right places, and convert dates
//result:=convertDates(stringReplace(s2,',Y,',',1,',[rfReplaceAll]));
result:=stringReplace(s2,',Y,',',1,',[rfReplaceAll]);
end;