Mercurial > hg > octave-lyh
changeset 16403:1de4ec2a856d
Matlab compatibility for strsplit()
* scripts/strings/strsplit.m: Matlab compatible version.
* NEWS: Mention break in backward compatibility.
* scripts/deprecated/javafields.m: Modify call to strsplit().
* scripts/deprecated/javamethods.m: ditto
* scripts/general/fieldnames.m: ditto
* scripts/general/int2str.m: ditto
* scripts/general/methods.m: ditto
* scripts/general/num2str.m: ditto
* scripts/help/gen_doc_cache.m: ditto
* scripts/help/help.m: ditto
* scripts/help/lookfor.m: ditto
* scripts/io/strread.m: ditto
* scripts/java/javaclasspath.m: ditto
* scripts/miscellaneous/compare_versions.m: ditto
* scripts/miscellaneous/computer.m: ditto
* scripts/miscellaneous/fact.m: ditto
* scripts/miscellaneous/tar.m: ditto
* scripts/miscellaneous/unpack.m: ditto
* scripts/miscellaneous/what.m: ditto
* scripts/miscellaneous/zip.m: ditto
* scripts/pkg/private/configure_make.m: ditto
* scripts/pkg/private/fix_depends.m: ditto
* scripts/pkg/private/generate_lookfor_cache.m: ditto
* scripts/pkg/private/list_forge_packages.m: ditto
* scripts/pkg/private/unload_packages.m: ditto
* scripts/pkg/private/write_index.m: ditto
* scripts/plot/private/__file_filter__.m: ditto
* scripts/plot/private/__fltk_file_filter__.m: ditto
* scripts/plot/private/__go_draw_axes__.m: ditto
* scripts/plot/private/__next_line_style__.m: ditto
* scripts/strings/untabify.m: ditto
* scripts/testfun/rundemos.m: ditto
* scripts/testfun/runtests.m: ditto
line wrap: on
line diff
--- a/NEWS +++ b/NEWS @@ -17,6 +17,45 @@ Summary of important user-visible changes for version 3.8: --------------------------------------------------------- + ** strsplit has been modified to be compatible with Matlab. There + are three instances where backward compatibility is broken. + + (1) Delimiters are now string vectors, not scalars. + + Octave's conventioal behavior + + strsplit ("1 2, 3", ", ") + ans = + { + [1,1] = 1 + [1,2] = 2 + [1,3] = + [1,4] = 3 + } + + Matlab compatible behavior + + strsplit ("1 2, 3", ", ") + ans = + { + [1,1] = 1 2 + [1,2] = 3 + } + + (2) By default, Matlab treats consecutive delimiters are as a single + delimiter. By default, Octave's conventional behavior was to return + an empty string. + + (3) Octave's conventional implementation supported splitting 2D + character arrays. The Matlab compatible version requires the input + string be a row vector. + + Where the conventional behavior is desired, the in-line function below + may be substituted. + + cstrsplit = @(str,del, collapsedelimiters = false) strsplit (strjoin ... + (cellstr (str), del(1)), num2cell (del(:)), collapsedelimiters); + ** Octave now supports nested functions with scoping rules that are compatible with Matlab. A nested function is one declared and defined within the body of another function. The nested function is only
--- a/scripts/deprecated/javafields.m +++ b/scripts/deprecated/javafields.m @@ -40,7 +40,7 @@ endif c_methods = javaMethod ("getFields", "org.octave.ClassHelper", javaobj); - method_list = strsplit (c_methods, ';'); + method_list = strsplit (c_methods, ';', false); if (nargout == 0) if (! isempty (method_list))
--- a/scripts/deprecated/javamethods.m +++ b/scripts/deprecated/javamethods.m @@ -40,7 +40,7 @@ endif cls_methods = javaMethod ("getMethods", "org.octave.ClassHelper", classname); - method_list = strsplit (cls_methods, ';'); + method_list = strsplit (cls_methods, ';', false); if (nargout == 0) if (! isempty (method_list))
--- a/scripts/general/fieldnames.m +++ b/scripts/general/fieldnames.m @@ -52,7 +52,7 @@ obj = class (obj); endif names_str = javaMethod ("getFields", "org.octave.ClassHelper", obj); - names = strsplit (names_str, ';'); + names = strsplit (names_str, ';', false); else error ("fieldnames: Invalid input argument"); endif
--- a/scripts/general/int2str.m +++ b/scripts/general/int2str.m @@ -73,7 +73,7 @@ endif tmp = sprintf (fmt, permute (n, [2, 1, 3 : nd])); tmp(end) = ""; - retval = char (strsplit (tmp, "\n")); + retval = char (strsplit (tmp, "\n", false)); endfunction
--- a/scripts/general/methods.m +++ b/scripts/general/methods.m @@ -43,14 +43,14 @@ mtds_list = __methods__ (obj); if (isempty (mtds_list)) mtds_str = javaMethod ("getMethods", "org.octave.ClassHelper", obj); - mtds_list = strsplit (mtds_str, ';'); + mtds_list = strsplit (mtds_str, ';', false); endif elseif (isjava (obj)) ## FIXME: Function prototype that excepts java obj exists, but doesn't ## work if obj is java.lang.String. Convert obj to classname. obj = class (obj); mtds_str = javaMethod ("getMethods", "org.octave.ClassHelper", obj); - mtds_list = strsplit (mtds_str, ';'); + mtds_list = strsplit (mtds_str, ';', false); else error ("methods: Invalid input argument"); endif
--- a/scripts/general/num2str.m +++ b/scripts/general/num2str.m @@ -118,7 +118,7 @@ fmt = cstrcat (deblank (repmat (fmt, 1, columns (x))), "\n"); nd = ndims (x); tmp = sprintf (fmt, permute (x, [2, 1, 3:nd])); - retval = strtrim (char (strsplit (tmp(1:end-1), "\n"))); + retval = strtrim (char (strsplit (tmp(1:end-1), "\n", false))); else # Complex matrix input if (nargin == 2) if (ischar (arg)) @@ -164,7 +164,7 @@ tmp = regexprep (tmp, " +i\n", "i\n"); tmp = regexprep (tmp, "( +)i", "i$1"); - retval = strtrim (char (strsplit (tmp(1:end-1), "\n"))); + retval = strtrim (char (strsplit (tmp(1:end-1), "\n", false))); endif endfunction
--- a/scripts/help/gen_doc_cache.m +++ b/scripts/help/gen_doc_cache.m @@ -117,7 +117,7 @@ function cache = gen_doc_cache_in_dir (directory) ## If 'directory' is not in the current path, add it so we search it - dir_in_path = ismember (directory, strsplit (path (), pathsep ())); + dir_in_path = ismember (directory, strsplit (path (), pathsep (), false)); # dirs not in path if (! iscell (directory))
--- a/scripts/help/help.m +++ b/scripts/help/help.m @@ -142,7 +142,7 @@ builtins = sprintf ("*** builtins:\n\n%s\n\n", list_in_columns (__builtins__ ())); - dirs = strsplit (path, pathsep); + dirs = strsplit (path, pathsep, false); flist = ""; for i = 2:numel (dirs) files = sort ({dir(fullfile (dirs{i}, "*.m")).name, ...
--- a/scripts/help/lookfor.m +++ b/scripts/help/lookfor.m @@ -66,10 +66,10 @@ endif ## Search functions in new path dirs. - orig_path = strsplit (__pathorig__ (), pathsep ()); + orig_path = strsplit (__pathorig__ (), pathsep (), false); ## ditto for path. - new_path = strsplit (path (), pathsep ()); + new_path = strsplit (path (), pathsep (), false); ## scratch out directories already covered by orig_path. if (had_core_cache)
--- a/scripts/io/strread.m +++ b/scripts/io/strread.m @@ -621,13 +621,13 @@ strrep (words(icol, jptr), fmt_words{ii}, ... [char(255) char(254)]); wrds(2:2:2*numel (words(icol, jptr))-1) = char (255); - wrds = strsplit ([wrds{:}], char (255)); + wrds = strsplit ([wrds{:}], char (255), false); words(icol, jptr) = ... wrds(find (cellfun ("isempty", strfind (wrds, char (254))))); wrds(find (cellfun ("isempty", strfind (wrds, char (254))))) ... = char (255); words(icol+1, jptr) = strsplit (strrep ([wrds{2:end}], ... - char (254), fmt_words{ii}), char (255)); + char (254), fmt_words{ii}), char (255), false); ## Former trailing literal may now be leading for next specifier --ii; fwptr = [fwptr(1:ii) (++fwptr(ii+1:end))]; @@ -699,7 +699,7 @@ case {"%0", "%1", "%2", "%3", "%4", "%5", "%6", "%7", "%8", "%9"} sw = regexp (fmt_words{m}, '\d', "once"); ew = regexp (fmt_words{m}, '[nfudsq]') - 1; - nfmt = strsplit (fmt_words{m}(2:ew), "."); + nfmt = strsplit (fmt_words{m}(2:ew), ".", false); swidth = str2double (nfmt{1}); switch fmt_words{m}(ew+1) case {"d", "u", "f", "n"} @@ -772,7 +772,7 @@ endif ## Split text string along delimiters - out = strsplit (text, sep, mult_dlms_s1); + out = strsplit (text, num2cell (sep(:)), mult_dlms_s1); if (index (sep, eol_char)); out = strrep (out, char (255), ''); endif ## In case of trailing delimiter, strip stray last empty word if (!isempty (out) && any (sep == text(end)))
--- a/scripts/java/javaclasspath.m +++ b/scripts/java/javaclasspath.m @@ -58,11 +58,11 @@ ## dynamic classpath dynamic_path = javaMethod ("getClassPath", "org.octave.ClassHelper"); - dynamic_path_list = strsplit (dynamic_path, pathsep ()); + dynamic_path_list = strsplit (dynamic_path, pathsep (), false); ## static classpath static_path = javaMethod ("getProperty", "java.lang.System", "java.class.path"); - static_path_list = strsplit (static_path, pathsep ()); + static_path_list = strsplit (static_path, pathsep (), false); if (numel (static_path_list) > 1) ## remove first element (which is .../octave.jar) static_path_list(1) = [];
--- a/scripts/miscellaneous/compare_versions.m +++ b/scripts/miscellaneous/compare_versions.m @@ -113,8 +113,8 @@ v2nochar = v2; endif - v1n = str2num (char (strsplit (v1nochar, "."))); - v2n = str2num (char (strsplit (v2nochar, "."))); + v1n = str2num (char (strsplit (v1nochar, ".", false))); + v2n = str2num (char (strsplit (v2nochar, ".", false))); if ((isempty (v1n) && isempty (v1c)) || (isempty (v2n) && isempty (v2c))) error ("compare_versions: given version strings are not valid: %s %s", v1, v2);
--- a/scripts/miscellaneous/computer.m +++ b/scripts/miscellaneous/computer.m @@ -49,7 +49,7 @@ function [c, maxsize, endian] = computer (a) if (nargin == 1 && ischar (a) && strcmpi (a, "arch")) - tmp = strsplit (octave_config_info ("canonical_host_type"), "-"); + tmp = strsplit (octave_config_info ("canonical_host_type"), "-", false); if (numel (tmp) == 4) c = sprintf ("%s-%s-%s", tmp{4}, tmp{3}, tmp{1}); else
--- a/scripts/miscellaneous/fact.m +++ b/scripts/miscellaneous/fact.m @@ -250,7 +250,7 @@ function out = wordwrap (w) cols = terminal_size ()(2); - wc = strsplit (w, " "); + wc = strsplit (w, " ", false); out = "\n"; i = 1; numwords = numel (wc); @@ -265,4 +265,4 @@ i++; endwhile out = cstrcat (out, "\n"); -endfunction \ No newline at end of file +endfunction
--- a/scripts/miscellaneous/tar.m +++ b/scripts/miscellaneous/tar.m @@ -59,7 +59,7 @@ if (output(end) == "\n") output(end) = []; endif - entries = strsplit (output, "\n"); + entries = strsplit (output, "\n", false); entries = entries'; endif
--- a/scripts/miscellaneous/unpack.m +++ b/scripts/miscellaneous/unpack.m @@ -194,7 +194,7 @@ if (output(length (output)) == "\n") output(length (output)) = []; endif - files = parser (strsplit (output, "\n"))'; + files = parser (strsplit (output, "\n", false))'; ## Move files if necessary if (needmove)
--- a/scripts/miscellaneous/what.m +++ b/scripts/miscellaneous/what.m @@ -32,7 +32,7 @@ d = pwd (); elseif (isempty (strfind (d, filesep ()))) ## Find the appropriate directory on the path. - p = strtrim (strsplit (path (), pathsep ())); + p = strtrim (strsplit (path (), pathsep (), false)); d = p{find (cellfun (@(x) ! isempty (strfind (x, d)), p))(end)}; else [status, msg, msgid] = fileattrib (d);
--- a/scripts/miscellaneous/zip.m +++ b/scripts/miscellaneous/zip.m @@ -62,7 +62,7 @@ if (entries(end) == "\n") entries(end) = []; endif - entries = strsplit (entries, "\n"); + entries = strsplit (entries, "\n", false); endif endfunction
--- a/scripts/pkg/private/configure_make.m +++ b/scripts/pkg/private/configure_make.m @@ -91,7 +91,7 @@ if (filenames(end) == "\n") filenames(end) = []; endif - filenames = strtrim (strsplit (filenames, "\n")); + filenames = strtrim (strsplit (filenames, "\n", false)); delete_idx = []; for i = 1:length (filenames) if (! all (isspace (filenames{i})))
--- a/scripts/pkg/private/fix_depends.m +++ b/scripts/pkg/private/fix_depends.m @@ -26,7 +26,7 @@ ## This function returns a cell of structures with the following fields: ## package, version, operator function deps_cell = fix_depends (depends) - deps = strtrim (strsplit (tolower (depends), ",")); + deps = strtrim (strsplit (tolower (depends), ",", false)); deps_cell = cell (1, length (deps)); ## For each dependency.
--- a/scripts/pkg/private/generate_lookfor_cache.m +++ b/scripts/pkg/private/generate_lookfor_cache.m @@ -23,7 +23,7 @@ ## @end deftypefn function generate_lookfor_cache (desc) - dirs = strtrim (strsplit (genpath (desc.dir), pathsep ())); + dirs = strtrim (strsplit (genpath (desc.dir), pathsep (), false)); for i = 1 : length (dirs) gen_doc_cache (fullfile (dirs{i}, "doc-cache"), dirs{i}); endfor
--- a/scripts/pkg/private/unload_packages.m +++ b/scripts/pkg/private/unload_packages.m @@ -35,7 +35,7 @@ endfor ## Get the current octave path. - p = strtrim (strsplit (path (), pathsep ())); + p = strtrim (strsplit (path (), pathsep (), false)); if (length (files) == 1 && strcmp (files{1}, "all")) ## Unload all.
--- a/scripts/pkg/private/write_index.m +++ b/scripts/pkg/private/write_index.m @@ -74,7 +74,7 @@ if (! isfield (desc, "categories")) error ("the DESCRIPTION file must have a Categories field, when no INDEX file is given"); endif - categories = strtrim (strsplit (desc.categories, ",")); + categories = strtrim (strsplit (desc.categories, ",", false)); if (length (categories) < 1) error ("the Category field is empty"); endif
--- a/scripts/plot/private/__file_filter__.m +++ b/scripts/plot/private/__file_filter__.m @@ -81,7 +81,7 @@ endswitch if (isempty (name)) - extlist = strsplit (filterext, ";"); + extlist = strsplit (filterext, ";", false); extlist = strrep (extlist, "*.", ""); extlist = toupper (extlist); extlist(end+1, :) = repmat ({","}, 1, length (extlist));
--- a/scripts/plot/private/__fltk_file_filter__.m +++ b/scripts/plot/private/__fltk_file_filter__.m @@ -34,7 +34,7 @@ for idx = 1 : r curr_ext = file_filter{idx, 1}; - curr_ext = strsplit (curr_ext, ";"); + curr_ext = strsplit (curr_ext, ";", false); if (length (curr_ext) > 1) curr_ext = regexprep (curr_ext, '\*\.', ',');
--- a/scripts/plot/private/__go_draw_axes__.m +++ b/scripts/plot/private/__go_draw_axes__.m @@ -2229,7 +2229,7 @@ endif if (ischar (ticklabel)) if (rows (ticklabel) == 1 && any (ticklabel == "|")) - ticklabel = strsplit (ticklabel, "|"); + ticklabel = strsplit (ticklabel, "|", false); else ticklabel = cellstr (ticklabel); endif
--- a/scripts/plot/private/__next_line_style__.m +++ b/scripts/plot/private/__next_line_style__.m @@ -41,7 +41,7 @@ elseif (reset || isempty (style_rotation)) style_rotation = get (gca (), "linestyleorder"); if (ischar (style_rotation)) - style_rotation = strsplit (style_rotation, "|"); + style_rotation = strsplit (style_rotation, "|", false); endif num_styles = length (style_rotation); style_index = 1;
--- a/scripts/strings/strsplit.m +++ b/scripts/strings/strsplit.m @@ -17,20 +17,33 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {[@var{cstr}] =} strsplit (@var{s}, @var{sep}) -## @deftypefnx {Function File} {[@var{cstr}] =} strsplit (@var{s}, @var{sep}, @var{strip_empty}) -## Split the string @var{s} using one or more separators @var{sep} and return -## a cell array of strings. Consecutive separators and separators at -## boundaries result in empty strings, unless @var{strip_empty} is true. -## The default value of @var{strip_empty} is false. +## @deftypefn {Function File} {[@var{cstr}] =} strsplit (@var{s}) +## @deftypefnx {Function File} {[@var{cstr}] =} strsplit (@var{s}, @var{del}) +## @deftypefnx {Function File} {[@var{cstr}] =} strsplit (@var{s}, @var{del}, @var{collapsedelimiters}) +## @deftypefnx {Function File} {[@var{cstr}] =} strsplit (@dots{}, @var{name}, @var{value}) +## @deftypefnx {Function File} {[@var{cstr}, @var{matches}] =} strsplit (@dots{}) +## Split the string @var{s} using the delimiters specified by @var{del} and return +## a cell array of strings. For a single delimiter, @var{del} may be a string, +## or a scalar cell-string. For multible delimiters, @var{del} must be a cell-string +## array. Unless @var{collapsedelimiters} is specified to be @var{false}, consecutive +## delimiters are collapsed into one. ## -## 2-D character arrays are split at separators and at the original column -## boundaries. +## The second output, @var{matches}, returns the delmiters which were matched +## in the original string. The matched delimiters are uneffected by the +## @var{collapsedelimiters}. ## ## Example: ## ## @example ## @group +## strsplit ("a b c") +## @result{} +## @{ +## [1,1] = a +## [1,2] = b +## [1,3] = c +## @} +## ## strsplit ("a,b,c", ",") ## @result{} ## @{ @@ -39,80 +52,221 @@ ## [1,3] = c ## @} ## -## strsplit (["a,b" ; "cde"], ",") +## strsplit ("a foo b,bar c", @{"\s", "foo", "bar"@}) +## @result{} +## @{ +## [1,1] = a +## [1,2] = b +## [1,3] = c +## @} +## +## strsplit ("a,,b, c", @{",", " "@}, false) +## @result{} +## @{ +## [1,1] = a +## [1,2] = +## [1,3] = b +## [1,4] = +## [1,5] = c +## @} +## +## @end group +## @end example +## +## Supported @var{name}/@var{value} pair arguments are; +## +## @itemize +## @item @code{collapsedelimiters} may take the value of @var{true} or @var{false} +## with the default being @var{false}. +## @item @code{delimitertype} may take the value of @code{simple} or @code{regularexpression}, +## with the default being @code{simple}. +## @end itemize +## +## Example: +## +## @example +## @group +## strsplit ("a foo b,bar c", ",|\\s|foo|bar", "delimitertype", "regularexpression") +## @result{} +## @{ +## [1,1] = a +## [1,2] = b +## [1,3] = c +## @} +## +## strsplit ("a,,b, c", "[, ]", false, "delimitertype", "regularexpression") +## @result{} +## @{ +## [1,1] = a +## [1,2] = +## [1,3] = b +## [1,4] = +## [1,5] = c +## @} +## +## strsplit ("a,\t,b, c", @{',', '\s'@}, "delimitertype", "regularexpression") ## @result{} ## @{ ## [1,1] = a ## [1,2] = b -## [1,3] = cde +## [1,3] = c ## @} ## @end group ## @end example -## @seealso{strtok} +## +## @seealso{strtok, regexp} ## @end deftypefn -function cstr = strsplit (s, sep, strip_empty = false) +function [result, matches] = strsplit (str, del, varargin) - if (nargin < 2 || nargin > 3) + args.collapsedelimiters = true; + args.delimitertype = "simple"; + + [reg, params] = parseparams (varargin); + + if (numel (reg) > 1) print_usage (); - elseif (! ischar (s) || ! ischar (sep)) - error ("strsplit: S and SEP must be string values"); - elseif (! isscalar (strip_empty)) - error ("strsplit: STRIP_EMPTY must be a scalar value"); + elseif (numel (reg) == 1) + if (islogical (reg{1}) || isnumeric (reg{1})) + args.collapsedelimiters = reg{1}; + else + print_usage (); + endif + endif + fields = fieldnames (args); + for n = 1:2:numel(params) + if (any (strcmpi (params{n}, fields))) + args.(lower(params{n})) = params{n+1}; + elseif (ischar (varargin{n})) + error ("strsplit:invalid_parameter_name", + sprintf ("strsplit: Invalid parameter name, `%s'", varargin{n})) + else + print_usage (); + endif + endfor + + # Save the length of the "delimitertype" parameter + length_deltype = numel (args.delimitertype); + + if (nargin == 1 || (nargin > 1 && (islogical (del) || isnumeric (del)))) + if (nargin > 1) + ## Second input is the "collapsedelimiters" parameter + args.collapsedelimiters = del; + endif + ## Set proper default for the delimiter type + if (strncmpi (args.delimitertype, "simple", numel (args.delimitertype))) + del = {" ","\f","\n","\r","\t","\v"}; + else + del = "\\s"; + endif + endif + + if (nargin < 1) + print_usage (); + elseif (! ischar (str) || (! ischar (del) && ! iscellstr (del))) + error ("strsplit: S and DEL must be string values"); + elseif (rows (str) > 1) + error ("strsplit: S must be a string value"); + elseif (! isscalar (args.collapsedelimiters)) + error ("strsplit: COLLAPSEDELIMITERS must be a scalar value"); + endif + + if (strncmpi (args.delimitertype, "simple", length_deltype)) + if (iscellstr (del)) + del = cellfun (@(x) regexp2simple (x, false), del, "uniformoutput", + false); + else + del = regexp2simple (del, false); + endif endif - if (isempty (s)) - cstr = cell (size (s)); - else - if (rows (s) > 1) - ## For 2-D arrays, add separator character at line boundaries - ## and transform to single string - s(:, end+1) = sep(1); - s = reshape (s.', 1, numel (s)); - s(end) = []; + if (isempty (str)) + result = {str}; + elseif (strncmpi (args.delimitertype, "regularexpression", length_deltype) + || strncmpi (args.delimitertype, "simple", length_deltype)) + if (iscellstr (del)) + del = sprintf ('%s|', del{:}); + del(end) = []; endif - - ## Split s according to delimiter - if (isscalar (sep)) - ## Single separator - idx = find (s == sep); - else - ## Multiple separators - idx = strchr (s, sep); + [result, ~, ~, ~, matches] = regexp (str, del, "split"); + if (args.collapsedelimiters) + result(cellfun (@isempty, result)) = []; + endif + if (strncmpi (args.delimitertype, "simple", length_deltype)) + matches = cellfun (@(x) regexp2simple (x, true), matches, + "uniformoutput", false); endif + else + error ("strsplit:invalid_delimitertype", + sprintf ("strsplit: Invalid DELIMITERTYPE")) + endif +endfunction - ## Get substring lengths. - if (isempty (idx)) - strlens = length (s); - else - strlens = [idx(1)-1, diff(idx)-1, numel(s)-idx(end)]; - endif - ## Remove separators. - s(idx) = []; - if (strip_empty) - ## Omit zero lengths. - strlens = strlens(strlens != 0); - endif - - ## Convert! - cstr = mat2cell (s, 1, strlens); +function str = regexp2simple (str, reverse = false) + rep = {'\', '[', ']', '{', '}', '$', '^', '(', ')', '*', '+', '.', '?', '|'}; + if (reverse) + ## backslash must go last + for r = numel(rep):-1:1 + str = strrep (str, [char(92), rep{r}], rep{r}); + endfor + else + ## backslash must go first + for r = 1:numel(rep) + str = strrep (str, rep{r}, [char(92), rep{r}]); + endfor endif - endfunction +%!shared str +%! str = "The rain in Spain stays mainly in the plain."; +% Split on all whitespace. +%!assert (strsplit (str), {"The", "rain", "in", "Spain", "stays", ... +%! "mainly", "in", "the", "plain."}) +% Split on "ain". +%!assert (strsplit (str, "ain"), {"The r", " in Sp", " stays m", ... +%! "ly in the pl", "."}) +% Split on " " and "ain" (treating multiple delimiters as one). +%!test +%! s = strsplit (str, '\s|ain', true, "delimitertype", "r"); +%! assert (s, {"The", "r", "in", "Sp", "stays", "m", "ly", "in", "the", "pl", "."}) +%!test +%! s = strsplit (str, "\\s|ain", true, "delimitertype", "r"); +%! assert (s, {"The", "r", "in", "Sp", "stays", "m", "ly", "in", "the", "pl", "."}) +%!test +%! [s, m] = strsplit (str, {"\\s", "ain"}, true, "delimitertype", "r"); +%! assert (s, {"The", "r", "in", "Sp", "stays", "m", "ly", "in", "the", "pl", "."}) +%! assert (m, {" ", "ain", " ", " ", "ain", " ", " ", "ain", " ", " ", " ", "ain"}) +% Split on " " and "ain", and treat multiple delimiters separately. +%!test +%! [s, m] = strsplit (str, {" ", "ain"}, "collapsedelimiters", false); +%! assert (s, {"The", "r", "", "in", "Sp", "", "stays", "m", "ly", "in", "the", "pl", "."}) +%! assert (m, {" ", "ain", " ", " ", "ain", " ", " ", "ain", " ", " ", " ", "ain"}) +%!assert (strsplit ("road to hell"), {"road", "to", "hell"}) %!assert (strsplit ("road to hell", " "), {"road", "to", "hell"}) -%!assert (strsplit ("road to^hell", " ^"), {"road", "to", "hell"}) -%!assert (strsplit ("road to--hell", " -", true), {"road", "to", "hell"}) -%!assert (strsplit (["a,bc";",de"], ","), {"a", "bc", char(ones(1,0)), "de "}) -%!assert (strsplit (["a,bc";",de"], ",", true), {"a", "bc", "de "}) -%!assert (strsplit (["a,bc";",de"], ", ", true), {"a", "bc", "de"}) +%!assert (strsplit ("road to^hell", {" ","^"}), {"road", "to", "hell"}) +%!assert (strsplit ("road to--hell", {" ","-"}, true), {"road", "to", "hell"}) +%!assert (strsplit (["a,bc,,de"], ",", false), {"a", "bc", "", "de"}) +%!assert (strsplit (["a,bc,de"], ",", true), {"a", "bc", "de"}) +%!assert (strsplit (["a,bc,de"], {","," "}, true), {"a", "bc", "de"}) +%!test +%! [s, m] = strsplit ("hello \t world", 1); +%! assert (s, {"hello", "world"}); +%! assert (m, {" ", "\t", " "}); + +%!assert (strsplit ("road to hell", " ", "delimitertype", "r"), {"road", "to", "hell"}) +%!assert (strsplit ("road to^hell", '\^| ', "delimitertype", "r"), {"road", "to", "hell"}) +%!assert (strsplit ("road to^hell", "[ ^]", "delimitertype", "r"), {"road", "to", "hell"}) +%!assert (strsplit ("road to--hell", "[ -]", false, "delimitertype", "r"), {"road", "", "", "to", "", "hell"}) +%!assert (strsplit (["a,bc,de"], ",", "delimitertype", "r"), {"a", "bc", "de"}) +%!assert (strsplit (["a,bc,,de"], ",", false, "delimitertype", "r"), {"a", "bc", "", "de"}) +%!assert (strsplit (["a,bc,de"], ",", true, "delimitertype", "r"), {"a", "bc", "de"}) +%!assert (strsplit (["a,bc,de"], "[, ]", true, "delimitertype", "r"), {"a", "bc", "de"}) +%!assert (strsplit ("hello \t world", 1, "delimitertype", "r"), {"hello", "world"}); %% Test input validation %!error strsplit () -%!error strsplit ("abc") %!error strsplit ("abc", "b", true, 4) -%!error <S and SEP must be string values> strsplit (123, "b") -%!error <S and SEP must be string values> strsplit ("abc", 1) -%!error <STRIP_EMPTY must be a scalar value> strsplit ("abc", "def", ones (3,3)) +%!error <S and DEL must be string values> strsplit (123, "b") +%!error <COLLAPSEDELIMITERS must be a scalar value> strsplit ("abc", "def", ones (3,3))