📄 readtext.m
字号:
% Keep quoted text together.
if(~isempty(opts.quotes)) % Should we look for quotes?
if((length(opts.quotes) == 1) || (opts.quotes(1) == opts.quotes(2))) % Opening char == ending.
exclE= find(text == opts.quotes(1));
exclS= exclE(1:2:end);
exclE= exclE(2:2:end);
else % Opening char ~= closing.
exclS= find(text == opts.quotes(1));
exclE= find(text == opts.quotes(2));
end
if((length(exclS) ~= length(exclE)) || any(exclS > exclE))
close(th); % Close waitbar or it'll linger.
error('Opening and closing quotes don''t match in %s.', opts.fname);
elseif(~isempty(exclS)) % We do have quoted text.
mywaitbar(0, th, '(readtext) Doing quotes...'); % Inform user.
r= 1;
rEnd= length(exclS);
n= 1;
nEnd= length(delimS);
result.quote= rEnd;
exclS(end+1)= 0; % This and next lines are needed in cases with only one quote in text.
exclE(end+1)= 0;
while((n <= nEnd) && (r <= rEnd)) % "Remove" delimiters and newlines within quotes.
while((r <= rEnd) && (delimS(n) > exclE(r))), r= r+1; end % Next end-quote after newline.
while((n <= nEnd) && (delimS(n) < exclS(r))), n= n+1; end % Next newline after strart-quote.
while((n <= nEnd) && (delimS(n) >= exclS(r)) && (delimS(n) <= exclE(r)))
delimS(n)= 0; % Newlines inside quote.
n= n+1;
end
mywaitbar(n/nEnd); % Update waitbar.
end
mywaitbar(1);
delimE= delimE(delimS > 0);
delimS= delimS(delimS > 0);
end
end
delimS= delimS-1; % Last char before delimiter.
delimE= [1 delimE(1:end-1)+1]; % First char after delimiter.
% Do the stuff: convert text to cell (and maybe numeric) array.
mywaitbar(0, th, sprintf('(readtext) Processing ''%s''...', opts.fname));
r= 1;
c= 1; % Presize data to optimise speed.
data= cell(length(divRow), ceil(length(delimS)/(length(divRow)-1)));
nums= zeros(size(data)); % Presize nums to optimise speed.
nEnd= length(delimS); % Prepare for a waitbar.
istextual= strcmp(opts.format, 'textual');
for n=1:nEnd
temp= strtrim(text(delimE(n):delimS(n))); % Textual item.
data{r, c}= temp; % Textual item.
if(~istextual)
lenT= length(temp);
if(lenT > 0)
% Try to get 123, 123i, 123i + 45, or 123i - 45
[a, count, errmsg, nextindex]= sscanf(temp, '%f %1[ij] %1[+-] %f', 4);
if(isempty(errmsg) && (nextindex > lenT))
if (count == 1), nums(r, c)= a;
elseif(count == 2), nums(r, c)= a(1)*i;
elseif(count == 4), nums(r, c)= a(1)*i + (44 - a(3))*a(4);
else nums(r, c)= NaN;
end
elseif(regexpi(temp, '[^0-9eij \.\+\-]', 'once')) % Remove non-numbers.
nums(r, c)= NaN;
else
nums(r, c)= s2n(temp, lenT); % Some other kind of complex number.
end
else nums(r, c)= NaN;
end
end
if(text(delimS(n)+1) == eol) % Next row.
result.min= min(result.min, c); % Find shortest row.
result.max= max(result.max, c); % Find longest row.
r= r+1;
c= 0;
if(bitand(r, 15) == 0), mywaitbar(n/nEnd); end % Update waitbar.
end
c= c+1;
end
% Clean up the conversion and do the result statistics.
mywaitbar(0, th, '(readtext) Cleaning up...'); % Inform user.
data= data(1:(r-1), 1:result.max); % In case we started off to big.
if(~strcmp(opts.format, 'textual')), nums= nums(1:(r-1), 1:result.max); end % In case we started off to big.
if(all(cellfun('isempty', data)))
data= {};
r= 1;
result.min= 0;
result.max= 0;
else
while((size(data, 2) > 1) && all(cellfun('isempty', data(end, :)))) % Remove empty last lines.
data= data(1:end-1, :);
nums= nums(1:end-1, :);
r= r-1;
end
while((size(data, 1) > 1) && all(cellfun('isempty', data(:, end)))) % Remove empty last columns.
data= data(:, 1:end-1);
nums= nums(:, 1:end-1);
c= c-1;
end
end
result.rows= r-1;
empties= cellfun('isempty', data); % Find empty items.
result.emptyMask= empties;
if(strcmp(opts.format, 'textual'))
result.numberMask= repmat(false, size(data)); % No numbers, all strings.
result.stringMask= ~empties; % No numbers, all strings.
data(empties)= {opts.op_empty}; % Set correct empty value.
else
if(isempty(data)), result.numberMask= [];
else result.numberMask= ~(isnan(nums) & ~strcmp(data, 'NaN')); % What converted well.
end
if(strcmp(opts.format, 'numeric'))
nums(empties)= opts.op_empty; % Set correct empty value.
data= nums; % Return the numeric array.
result.stringMask= ~(empties | result.numberMask); % Didn't convert well: so strs.
else
data(result.numberMask)= num2cell(nums(result.numberMask)); % Copy back numerics.
data(empties)= {opts.op_empty}; % Set correct empty value.
result.stringMask= cellfun('isclass', data, 'char'); % Well, the strings.
end
end
result.empty= sum(result.emptyMask(:)); % Count empties.
result.numberMask= result.numberMask & ~result.emptyMask; % Empties don't count.
result.number= sum(result.numberMask(:)); % Count numbers.
result.stringMask= result.stringMask & ~result.emptyMask; % Empties don't count.
result.string= sum(result.stringMask(:)); % Count strings.
close(th); % Removing the waitbar.
end
function x= s2n(s, lenS)
x= NaN;
% Try to get 123 + 23i or 123 - 23i
[a,count,errmsg,nextindex] = sscanf(s,'%f %1[+-] %f %1[ij]',4);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 4), x= a(1) + (44 - a(2))*a(3)*i;
end
return
end
% Try to get i, i + 45, or i - 45
[a,count,errmsg,nextindex] = sscanf(s,'%1[ij] %1[+-] %f',3);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 1), x= i;
elseif(count == 3), x= i + (44 - a(2))*a(3);
end
return
end
% Try to get 123 + i or 123 - i
[a,count,errmsg,nextindex] = sscanf(s,'%f %1[+-] %1[ij]',3);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 1), x= a(1);
elseif(count == 3), x= a(1) + (44 - a(2))*i;
end
return
end
% Try to get -i, -i + 45, or -i - 45
[a,count,errmsg,nextindex] = sscanf(s,'%1[+-] %1[ij] %1[+-] %f',4);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 2), x= (44 - a(1))*i;
elseif(count == 4), x= (44 - a(1))*i + (44 - a(3))*a(4);
end
return
end
% Try to get 123 + 23*i or 123 - 23*i
[a,count,errmsg,nextindex] = sscanf(s,'%f %1[+-] %f %1[*] %1[ij]',5);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 5), x= a(1) + (44 - a(2))*a(3)*i;
end
return
end
% Try to get 123*i, 123*i + 45, or 123*i - 45
[a,count,errmsg,nextindex] = sscanf(s,'%f %1[*] %1[ij] %1[+-] %f',5);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 1), x= a;
elseif(count == 3), x= a(1)*i;
elseif(count == 5), x= a(1)*i + (44 - a(4))*a(5);
end
return
end
% Try to get i*123 + 45 or i*123 - 45
[a,count,errmsg,nextindex] = sscanf(s,'%1[ij] %1[*] %f %1[+-] %f',5);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 1), x= i;
elseif(count == 3), x= i*a(3);
elseif(count == 5), x= i*a(3) + (44 - a(4))*a(5);
end
return
end
% Try to get -i*123 + 45 or -i*123 - 45
[a,count,errmsg,nextindex] = sscanf(s,'%1[+-] %1[ij] %1[*] %f %1[+-] %f',6);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 2), x= (44 - a(1))*i;
elseif(count == 4), x= (44 - a(1))*i*a(4);
elseif(count == 6), x= (44 - a(1))*i*a(4) + (44 - a(5))*a(6);
end
return
end
% Try to get 123 + i*45 or 123 - i*45
[a,count,errmsg,nextindex] = sscanf(s,'%f %1[+-] %1[ij] %1[*] %f',5);
if(isempty(errmsg) && (nextindex > lenS))
if(count == 5), x= a(1) + (44 - a(2))*i*a(5);
end
return
end
% None of the above cases.
x= NaN;
end
function emptywaitbar(varargin)
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -