function varargout = Explode(vect,splitvect,mode) % outputcell = Explode(vect,splitvect,mode) % [out1,out2,...] = Explode(vect,splitvect,mode) % % Split a string or vector VECT by a string, scalar or vector SPLITSVECT. % Output OUTPUTCELL will be returned as an array of cells. % % Both VECT and SPLITSVECT must be a string or numeric vector of length 1 % or more. % % The way this function handles its input is different for strings and % numeric datatypes. % % strings % SPLITSVECT can be specified using two formats (MODE): % If MODE is not specified, 'fixed' will be used % % 'fixed' : a fixed string, which will be used literally to split % VECT. Some character combinations have a special meaning: % \b Backspace % \f Form feed % \n New line % \r Carriage return % \t Horizontal tab % example: % s1 = 'resp32|me too|"get over here"'; % s2 = Explode(s1,'|'); or s2 = Explode(s1,'|','fixed'); % s2(:) % ans = % 'resp32' % 'me too' % '"get over here"' % % 'variable' : if you want to split the input with on a string that % matches a certain pattern. % specify this pattern using a regular expression, % see "doc regexp" % example: % s1 = '|fff|ja|fdf|er|fft|fofr|'; % s2 = Explode(s1,'f.f','variable'); % . means any character % s2(:) % ans = % '|' % '|ja|' % '|er|fft|' % 'r|' % % numerical vectors % SPLITSVECT can be specified using two formats (MODE): % If MODE is not specified, 'fixed' will be used % NB: splitting floats works, but precision will be lost % % 'fixed' : a fixed number or sequence of numbers, which will be used % literally to split the vector. % example: % n1 = [inf 33 12 45 13 nan 46 74 12 45 15 64]; % n2 = Explode(n1,[12 45]); of n2 = Explode(s1,[12 45],'fixed'); % n2(:) % ans = % [Inf 33] % [ 13 NaN 46 74] % [ 15 64] % n2 = Explode(n1,12); % n2(:) % ans = % [Inf 33] % [ 45 13 NaN 46 74] % [ 45 15 64] % % 'variable' : If you want to split on a sequence of numbers that % contains (a) wildcard(s). Each wilcard can match a single % item in the vector. % NaN specifies a wildcard. When using 'variable' for % numeric input, you can thus no longer use NaN in your % pattern. % example: % n1 = [inf 33 12 45 13 nan 46 74 12 35 64 13 21]; % n2 = Explode(n1,[12 nan 13],'variable'); % n2(:) % ans = % [Inf 33] % [NaN 46 74 12 35 64 13 21] % % n2 = Explode(n1,[12 nan nan 13],'variable'); % n2(:) % ans = % [Inf 33 12 45 13 NaN 46 74] % [21] % DN 2008 % DN 2008-07-31 Added checking of MATLAB version % DN 2010-12-29 Fixed version check now that subversion is over .9... % DN 2011-09-05 Fixed a lot of numeric splitting. Now deals with floats % correctly (though precision is still lost), supports % variable number of outputs and clarified meaning of % wildcard for number splitting. if ~IsOctave v = ver('matlab'); v = v(1).Version; v = sscanf(v, '%i.%i.%i'); psychassert((v(1) == 7 && v(2) > 2) || v(1) > 7,'Need at least MATLAB R2006b'); else % we don't have the 'split' option in regexp, at least in version 3.2.4 % strsplit only splits on single delimiters, so not an option error('Explode is not supported on Octave'); end if nargin==3 switch mode case 'fixed' qfixed = true; case 'variable' qfixed = false; otherwise error('Invalid mode "%s" specified, use "fixed" (default) or "variable"',mode); end else qfixed = true; end if ischar(vect) if qfixed % prepare splitsvect for use with regexp - e.g. convert return to % the regexp pattern for return splitvect = regexprep(splitvect,'\\([^bfnrt])','\\\\$1'); % escape backslash unless followed by a special character end strc = regexp(vect,splitvect,'split'); elseif isnumeric(vect) dtype = class(vect); vect = num2str(vect(:)'); % make sure its a columnvector and convert to string qisNaN = all(isnan(splitvect(:))); splitvect = num2str(splitvect(:)'); splitvect = regexprep(splitvect,'\s+','\\s+'); if ~qfixed psychassert(~qisNaN,'When mode==''variable'', split vector cannot contain only nan, cannot split on only a wildcard') splitvect = regexprep(splitvect,'[nN]a[nN]','[\\w\\d\\.]+?'); end split = regexp(vect,['(?<=\s)' splitvect '(?=\s)'],'split'); func = @(x)cast(str2num(x),dtype); %#ok strc = cellfun(func,split,'UniformOutput',false); else error('input type %s not supported',class(vect)); end if nargout <= 1 varargout{1} = strc; else varargout = strc; end