cosmo strsplit

function [split, nsplit] = cosmo_strsplit(string, delim, varargin)
    % splits a string based on another delimiter string
    %
    % [split,n]=cosmo_strsplit(string[,delim,][pos1, delim2, pos2, delim2,...])
    %
    % Inputs:
    %   string          input to be split
    %   delim           delimiter string. delim can contain backslash-escaped
    %                   characters that are interpreted by sprintf; for
    %                   example '\t', '\n' and '\\' represent a tab, newline
    %                   and backslash character, respectively.
    %                   If omitted or equal to [], then the string is split
    %                   based on whitespaces occurring in string
    %
    %   pos             (optional) a single index indicating which split part
    %                   should be returned. If string is split in N elements,
    %                   then a negative value for pos is equivalent to pos+1+N
    %                   (similar to Python). For example, pos=-1 means that the
    %                   last element is returned, and pos=-2 means that the
    %                   element before the last element is returned.
    %                   If omitted a cell with all parts are returned.
    %   delim*          (optional) subsequent delimiters applied after applying
    %                   pos. It requires that the preceding pos has a single
    %                   value.
    %
    % Output:
    %   split           when the last argument is non-positional, split is a
    %                   cell with the string split by delim. When there are N
    %                   non-overlapping occurrences of delim in string, then
    %                   split has N+1 elements, and the string
    %                   [delim split{1} delim split{2} ... split{N} delim]
    %                   is equal to string.
    %                   If the last argument is positional, then split is
    %                   a string with value split_{pos} where split_ is the
    %                   result if pos where not the last argument.
    %   n               the number of elements in split, if split is a cell;
    %                   0 otherwise
    %
    % Examples:
    %   % split by '*'
    %   cosmo_strsplit('A*AbbAbA*AbA*A*Ab','*')
    %   %||      { 'A'    'AbbAbA'    'AbA'    'A'    'Ab' }
    %
    %   % split by 'A*A'
    %   cosmo_strsplit('A*AbbAbA*AbA*A*Ab','A*A')
    %   %||  { ''    'bbAb'    'b'    '*Ab' }
    %
    %   % take second element after split
    %   cosmo_strsplit('A*AbbAbA*AbA*A*Ab','A*A',2)
    %   %||  'bbAb'
    %
    %   % get last element after split
    %   cosmo_strsplit('A*AbbAbA*AbA*A*Ab','A*A',-1)
    %   %||  '*Ab'
    %
    %   % split twice, first on 'A*A', take second element, then on 'A'
    %   cosmo_strsplit('A*AbbAbA*AbA*A*Ab','A*A',2,'A')
    %   %||    { 'bb'    'b' }
    %
    %   % take first element after second split
    %   cosmo_strsplit('A*AbbAbA*AbA*A*Ab','A*A',2,'A',1)
    %   %||  'bb'
    %
    %   % illustrate effect of not using a delimiter string
    %   % (which causes the string to be split by whitespace) and using
    %   % a space as delimiter
    %   cosmo_strsplit(' CoSMoMVPA makes live...  easy!')
    %   %||   { 'CoSMoMVPA'    'makes'    'live...'    'easy!' }
    %   cosmo_strsplit(' CoSMoMVPA makes live...  easy!',' ')
    %   %||   {  ''    'CoSMoMVPA'    'makes'    'live...'    ''    'easy!' }
    %
    % #   For CoSMoMVPA's copyright information and license terms,   #
    % #   see the COPYING file distributed with CoSMoMVPA.           #

    if ~ischar(string)
        error('first argument must be a string');
    end

    if nargin < 2 || (~ischar(delim) && isequal(delim, []))
        % split by white-space
        split = regexp(string, '(\S)*', 'match');
    elseif ischar(delim)
        pat = regexptranslate('escape', sprintf(delim));
        split = regexp(string, pat, 'split');
    else
        error('Second argument, if provided, must be a string');
    end

    nsplit = numel(split);

    if nargin > 2
        pos = varargin{1};
        if numel(pos) ~= 1
            error('Need scalar position argument');
        end

        if pos < 0
            nsplit = numel(split);
            pos = pos + nsplit + 1;
        end

        % select element indicated by index
        split = split{pos};
        nsplit = 0;

        if nargin > 3
            me = str2func(mfilename()); % make imune to renaming
            [split, nsplit] = me(split, varargin{2:end}); % use recursion
        end
    end