Strings
*******

A string constant consists of a sequence of characters enclosed in either double-quote or single-quote marks.  For example, both of the following expressions

     "parrot"
     'parrot'

represent the string whose contents are parrot.  Strings in Octave can be of any length.

Since the single-quote mark is also used for the transpose operator (see Arithmetic Ops) but double-quote marks have no other purpose in Octave, it is best to use double-quote marks to denote strings.

Strings can be concatenated using the notation for defining matrices.  For example, the expression

     [ "foo" , "bar" , "baz" ]

produces the string whose contents are foobarbaz.  See Numeric Data Types, for more information about creating matrices.

While strings can in principle store arbitrary content, most functions expect them to be UTF-8 encoded Unicode strings.

Furthermore, it is possible to create a string without actually writing a text. The function blanks creates a string of a given length consisting only of blank characters (ASCII code 32).

 -- STR =: blanks (N)
     Return a string of N blanks.

     For example:

          blanks (10);
          whos ans
               =>
                Attr Name        Size                     Bytes  Class
                ==== ====        ====                     =====  =====
                     ans         1x10                        10  char

     repmat

Escape Sequences in String Constants
====================================

In double-quoted strings, the backslash character is used to introduce escape sequences that represent other characters.  For example, \n embeds a newline character in a double-quoted string and \" embeds a double quote character.  In single-quoted strings, backslash is not a special character.  Here is an example showing the difference:

     double ("\n")
         => 10
     double ('\n')
         => [ 92 110 ]

Here is a table of all the escape sequences used in Octave (within double quoted strings).  They are the same as those used in the C programming language.

\\
     Represents a literal backslash, \.

\"
     Represents a literal double-quote character, ".

\'
     Represents a literal single-quote character, '.

\0
     Represents the null character, control-@, ASCII code 0.

\a
     Represents the ``alert'' character, control-g, ASCII code 7.

\b
     Represents a backspace, control-h, ASCII code 8.

\f
     Represents a formfeed, control-l, ASCII code 12.

\n
     Represents a newline, control-j, ASCII code 10.

\r
     Represents a carriage return, control-m, ASCII code 13.

\t
     Represents a horizontal tab, control-i, ASCII code 9.

\v
     Represents a vertical tab, control-k, ASCII code 11.

\NNN
     Represents the octal value NNN, where NNN are one to three digits between 0 and 7.  For example, the code for the ASCII ESC (escape) character is \033.

\xHH...
     Represents the hexadecimal value HH, where HH are hexadecimal digits (0 through 9 and either A through F or a through f).  Like the same construct in ANSI C, the escape sequence continues until the first non-hexadecimal digit is seen. However, using more than two hexadecimal digits produces undefined results.

In a single-quoted string there is only one escape sequence: you may insert a single quote character using two single quote characters in succession.  For example,

     'I can''t escape'
         => I can't escape

In scripts the two different string types can be distinguished if necessary by using is_dq_string and is_sq_string.

 -- TF =: is_dq_string (X)
     Return true if X is a double-quoted character string. is_sq_string, ischar

 -- TF =: is_sq_string (X)
     Return true if X is a single-quoted character string. is_dq_string, ischar

Character Arrays
================

The string representation used by Octave is an array of characters, so internally the string "dddddddddd" is actually a row vector of length 10 containing the value 100 in all places (100 is the ASCII code of "d").  This lends itself to the obvious generalization to character matrices.  Using a matrix of characters, it is possible to represent a collection of same-length strings in one variable.  The convention used in Octave is that each row in a character matrix is a separate string, but letting each column represent a string is equally possible.

The easiest way to create a character matrix is to put several strings together into a matrix.

     collection = [ "String #1"; "String #2" ];

This creates a 2-by-9 character matrix.

The function ischar can be used to test if an object is a character matrix.

 -- TF =: ischar (X)
     Return true if X is a character array. isfloat, isinteger, islogical, isnumeric, isstring, iscellstr, isa

 -- TF =: isstring (S)
     Return true if S is a string array.

     A string array is a data type that stores strings (row vectors of characters) at each element in the array.  It is distinct from character arrays which are N-dimensional arrays where each element is a single 1x1 character.  It is also distinct from cell arrays of strings which store strings at each element, but use cell indexing {} to access elements rather than string arrays which use ordinary array indexing ().

     Programming Note: Octave does not yet implement string arrays so this function will always return false. ischar, iscellstr, isfloat, isinteger, islogical, isnumeric, isa

To test if an object is a string (i.e., a 1xN row vector of characters and not a character matrix) you can use the ischar function in combination with the isrow function as in the following example:

     ischar (collection)
          => 1

     ischar (collection) && isrow (collection)
          => 0

     ischar ("my string") && isrow ("my string")
          => 1

One relevant question is, what happens when a character matrix is created from strings of different length.  The answer is that Octave puts blank characters at the end of strings shorter than the longest string.  It is possible to use a different character than the blank character using the string_fill_char function.

 -- VAL =: string_fill_char ()
 -- OLD_VAL =: string_fill_char (NEW_VAL)
 -- OLD_VAL =: string_fill_char (NEW_VAL, "local")
     Query or set the internal variable used to pad all rows of a character matrix to the same length.

     The value must be a single character and the default is " " (a single space).  For example:

          string_fill_char ("X");
          [ "these"; "are"; "strings" ]
              =>  "theseXX"
                  "areXXXX"
                  "strings"

     When called from inside a function with the "local" option, the variable is changed locally for the function and any subroutines it calls. The original variable value is restored when exiting the function.

Another useful function to control the text justification in this case is the strjust function.

 -- STR =: strjust (S)
 -- STR =: strjust (S, POS)
     Return the text, S, justified according to POS, which may be "left", "center", or "right".

     If POS is omitted it defaults to "right".

     Null characters are replaced by spaces.  All other character data are treated as non-white space.

     Example:

          strjust (["a"; "ab"; "abc"; "abcd"])
               =>
                  "   a"
                  "  ab"
                  " abc"
                  "abcd"

     deblank, strrep, strtrim, untabify

This shows a problem with character matrices.  It simply isn't possible to represent strings of different lengths.  The solution is to use a cell array of strings, which is described in Cell Arrays of Strings.

String Operations
=================

Octave supports a wide range of functions for manipulating strings. Since a string is just a matrix, simple manipulations can be accomplished using standard operators.  The following example shows how to replace all blank characters with underscores.

     quote = ...
       "First things first, but not necessarily in that order";
     quote( quote == " " ) = "_"
     => quote =
         First_things_first,_but_not_necessarily_in_that_order

For more complex manipulations, such as searching, replacing, and general regular expressions, the following functions come with Octave.

Common String Operations
------------------------

The following functions are useful to perform common String operations.

 -- Y =: lower (S)
 -- Y =: tolower (S)
     Return a copy of the string or cell string S, with each uppercase character replaced by the corresponding lowercase one; non-alphabetic characters are left unchanged.

     For example:

          lower ("MiXeD cAsE 123")
              => "mixed case 123"

     Programming Note: tolower is an alias for lower and either name can be used in Octave.

     upper

 -- Y =: upper (S)
 -- Y =: toupper (S)
     Return a copy of the string or cell string S, with each lowercase character replaced by the corresponding uppercase one; non-alphabetic characters are left unchanged.

     For example:

          upper ("MiXeD cAsE 123")
              => "MIXED CASE 123"

     Programming Note: toupper is an alias for upper and either name can be used in Octave.

     lower

 -- S =: deblank (S)
     Remove trailing whitespace and nulls from S.

     If S is a matrix, DEBLANK trims each row to the length of the longest string.  If S is a cell array of strings, operate recursively on each string element.

     Examples:

          deblank ("    abc  ")
               =>  "    abc"

          deblank ([" abc   "; "   def   "])
               =>  [" abc  " ; "   def"]

     strtrim

 -- S =: strtrim (S)
     Remove leading and trailing whitespace from S.

     If S is a matrix, STRTRIM trims each row to the length of longest string.  If S is a cell array of strings, operate recursively on each string element.

     For example:

          strtrim ("    abc  ")
               =>  "abc"

          strtrim ([" abc   "; "   def   "])
               =>  ["abc  "  ; "  def"]

     deblank

 -- S =: strtrunc (S, N)
     Truncate the character string S to length N.

     If S is a character matrix, then the number of columns is adjusted.

     If S is a cell array of strings, then the operation is performed on each cell element and the new cell array is returned.

 -- STR =: untabify (T)
 -- STR =: untabify (T, TW)
 -- STR =: untabify (T, TW, DEBLANK)
     Replace TAB characters in T with spaces.

     The input, T, may be either a 2-D character array, or a cell array of character strings.  The output is the same class as the input.

     The tab width is specified by TW, and defaults to eight.

     If the optional argument DEBLANK is true, then the spaces will be removed from the end of the character data.

     The following example reads a file and writes an untabified version of the same file with trailing spaces stripped.

          fid = fopen ("tabbed_script.m");
          text = char (fread (fid, "uchar")');
          fclose (fid);
          fid = fopen ("untabified_script.m", "w");
          text = untabify (strsplit (text, "\n"), 8, true);
          fprintf (fid, "%s\n", text{:});
          fclose (fid);

     strjust, strsplit, deblank

 -- NEWSTR =: do_string_escapes (STRING)
     Convert escape sequences in STRING to the characters they represent.

     Escape sequences begin with a leading backslash ('\') followed by 1--3 characters (.e.g., "\n" => newline). undo_string_escapes

 -- NEWSTR =: undo_string_escapes (STRING)
     Convert special characters in STRING back to their escaped forms.

     For example, the expression

          BELL = "\a";

     assigns the value of the alert character (control-g, ASCII code 7) to the string variable bell.  If this string is printed, the system will ring the terminal bell (if it is possible).  This is normally the desired outcome.  However, sometimes it is useful to be able to print the original representation of the string, with the special characters replaced by their escape sequences.  For example,

          octave:13> undo_string_escapes (bell)
          ans = \a

     replaces the unprintable alert character with its printable representation. do_string_escapes

Concatenating Strings
---------------------

Strings can be concatenated using matrix notation (see Strings, Character Arrays) which is often the most natural method.  For example:

     fullname = [fname ".txt"];
     email = ["<" user "@" domain ">"];

In each case it is easy to see what the final string will look like.  This method is also the most efficient.  When using matrix concatenation the parser immediately begins joining the strings without having to process the overhead of a function call and the input validation of the associated function.

The newline function can be used to join strings such that they appear as multiple lines of text when displayed.

 -- C =: newline
     Return the character corresponding to a newline.

     This is equivalent to "\n".

     Example Code

          joined_string = [newline "line1" newline "line2"]
          =>
          line1
          line2

     strcat, strjoin, strsplit

In addition, there are several other functions for concatenating string objects which can be useful in specific circumstances: char, strvcat, strcat, and cstrcat.  Finally, the general purpose concatenation functions can be used: see cat, horzcat, and vertcat.

  * All string concatenation functions except cstrcat convert numerical input into character data by taking the corresponding UTF-8 character for each element (or multi-byte sequence), as in the following example:

          char ([98, 97, 110, 97, 110, 97])
             => banana

     For conversion between locale encodings and UTF-8, see unicode2native and native2unicode.

  * char and strvcat concatenate vertically, while strcat and cstrcat concatenate horizontally.  For example:

          char ("an apple", "two pears")
              => an apple
                 two pears

          strcat ("oc", "tave", " is", " good", " for you")
               => octave is good for you

  * char generates an empty row in the output for each empty string in the input.  strvcat, on the other hand, eliminates empty strings.

          char ("orange", "green", "", "red")
              => orange
                 green

                 red

          strvcat ("orange", "green", "", "red")
              => orange
                 green
                 red

  * All string concatenation functions except cstrcat also accept cell array data (see Cell Arrays).  char and strvcat convert cell arrays into character arrays, while strcat concatenates within the cells of the cell arrays:

          char ({"red", "green", "", "blue"})
               => red
                  green

                  blue

          strcat ({"abc"; "ghi"}, {"def"; "jkl"})
               =>
                  {
                    [1,1] = abcdef
                    [2,1] = ghijkl
                  }

  * strcat removes trailing white space in the arguments (except within cell arrays), while cstrcat leaves white space untouched.  Both kinds of behavior can be useful as can be seen in the examples:

          strcat (["dir1";"directory2"], ["/";"/"], ["file1";"file2"])
               => dir1/file1
                  directory2/file2

          cstrcat (["thirteen apples"; "a banana"], [" 5$";" 1$"])
                => thirteen apples 5$
                   a banana        1$

     Note that in the above example for cstrcat, the white space originates from the internal representation of the strings in a string array (see Character Arrays).

 -- C =: char (A)
 -- C =: char (A, ...)
 -- C =: char (STR1, STR2, ...)
 -- C =: char (CELL_ARRAY)
     Create a string array from one or more numeric matrices, character matrices, or cell arrays.

     Arguments are concatenated vertically.  The returned values are padded with blanks as needed to make each row of the string array have the same length. Empty input strings are significant and will concatenated in the output.

     For numerical input, each element is converted to the corresponding ASCII character.  A range error results if an input is outside the ASCII range (0-255).

     For cell arrays, each element is concatenated separately.  Cell arrays converted through char can mostly be converted back with cellstr.  For example:

          char ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
             => ["abc "
                 "    "
                 "98  "
                 "99  "
                 "d   "
                 "str1"
                 "half"]

     strvcat, cellstr

 -- C =: strvcat (A)
 -- C =: strvcat (A, ...)
 -- C =: strvcat (STR1, STR2, ...)
 -- C =: strvcat (CELL_ARRAY)
     Create a character array from one or more numeric matrices, character matrices, or cell arrays.

     Arguments are concatenated vertically.  The returned values are padded with blanks as needed to make each row of the string array have the same length. Unlike char, empty strings are removed and will not appear in the output.

     For numerical input, each element is converted to the corresponding ASCII character.  A range error results if an input is outside the ASCII range (0-255).

     For cell arrays, each element is concatenated separately.  Cell arrays converted through strvcat can mostly be converted back with cellstr.  For example:

          strvcat ([97, 98, 99], "", {"98", "99", 100}, "str1", ["ha", "lf"])
                => ["abc "
                    "98  "
                    "99  "
                    "d   "
                    "str1"
                    "half"]

     char, strcat, cstrcat

 -- STR =: strcat (S1, S2, ...)
     Return a string containing all the arguments concatenated horizontally.

     If the arguments are cell strings, strcat returns a cell string with the individual cells concatenated.  For numerical input, each element is converted to the corresponding ASCII character.  Trailing white space for any character string input is eliminated before the strings are concatenated.  Note that cell string values do not have whitespace trimmed.

     For example:

          strcat ("|", " leading space is preserved", "|")
              => | leading space is preserved|

          strcat ("|", "trailing space is eliminated ", "|")
              => |trailing space is eliminated|

          strcat ("homogeneous space |", "  ", "| is also eliminated")
              => homogeneous space || is also eliminated

          s = [ "ab"; "cde" ];
          strcat (s, s, s)
              =>
                  "ababab   "
                  "cdecdecde"

          s = { "ab"; "cd " };
          strcat (s, s, s)
              =>
                  {
                    [1,1] = ababab
                    [2,1] = cd cd cd
                  }

     cstrcat, char, strvcat

 -- STR =: cstrcat (S1, S2, ...)
     Return a string containing all the arguments concatenated horizontally with trailing white space preserved.

     For example:

          cstrcat ("ab   ", "cd")
                => "ab   cd"

          s = [ "ab"; "cde" ];
          cstrcat (s, s, s)
                => "ab ab ab "
                   "cdecdecde"

     strcat, char, strvcat

Splitting and Joining Strings
-----------------------------

 -- STR =: substr (S, OFFSET)
 -- substr: (S, OFFSET, LEN)
     Return the substring of S which starts at character number OFFSET and is LEN characters long.

     Position numbering for offsets begins with 1.  If OFFSET is negative, extraction starts that far from the end of the string.

     If LEN is omitted, the substring extends to the end of S.  A negative value for LEN extracts to within LEN characters of the end of the string

     Examples:

          substr ("This is a test string", 6, 9)
               => "is a test"
          substr ("This is a test string", -11)
               => "test string"
          substr ("This is a test string", -11, -7)
               => "test"

     This function is patterned after the equivalent function in Perl.

 -- [TOK, REM] =: strtok (STR)
 -- [TOK, REM] =: strtok (STR, DELIM)

     Find all characters in the string STR up to, but not including, the first character which is in the string DELIM.

     STR may also be a cell array of strings in which case the function executes on every individual string and returns a cell array of tokens and remainders.

     Leading delimiters are ignored.  If DELIM is not specified, whitespace is assumed.

     If REM is requested, it contains the remainder of the string, starting at the first delimiter.

     Examples:

          strtok ("this is the life")
               => "this"

          [tok, rem] = strtok ("14*27+31", "+-*/")
               =>
                  tok = 14
                  rem = *27+31

     index, strsplit, strchr, isspace

 -- [CSTR] =: strsplit (STR)
 -- [CSTR] =: strsplit (STR, DEL)
 -- [CSTR] =: strsplit (..., NAME, VALUE)
 -- [CSTR, MATCHES] =: strsplit (...)
     Split the string STR using the delimiters specified by DEL and return a cell string array of substrings.

     If a delimiter is not specified the string is split at whitespace {" ", "\f", "\n", "\r", "\t", "\v"}.  Otherwise, the delimiter, DEL must be a string or cell array of strings.  By default, consecutive delimiters in the input string S are collapsed into one resulting in a single split.

     Supported NAME/VALUE pair arguments are:

       * COLLAPSEDELIMITERS which may take the value of true (default) or false.

       * DELIMITERTYPE which may take the value of "simple" (default) or "regularexpression".  A simple delimiter matches the text exactly as written.  Otherwise, the syntax for regular expressions outlined in regexp is used.

     The optional second output, MATCHES, returns the delimiters which were matched in the original string.

     Examples with simple delimiters:

          strsplit ("a b c")
                =>
                    {
                      [1,1] = a
                      [1,2] = b
                      [1,3] = c
                    }

          strsplit ("a,b,c", ",")
                =>
                    {
                      [1,1] = a
                      [1,2] = b
                      [1,3] = c
                    }

          strsplit ("a foo b,bar c", {" ", ",", "foo", "bar"})
                =>
                    {
                      [1,1] = a
                      [1,2] = b
                      [1,3] = c
                    }

          strsplit ("a,,b, c", {",", " "}, "collapsedelimiters", false)
                =>
                    {
                      [1,1] = a
                      [1,2] =
                      [1,3] = b
                      [1,4] =
                      [1,5] = c
                    }

     Examples with regularexpression delimiters:

          strsplit ("a foo b,bar c", ',|\s|foo|bar', ...
                    "delimitertype", "regularexpression")
          =>
          {
                      [1,1] = a
                      [1,2] = b
                      [1,3] = c
          }

          strsplit ("a,,b, c", '[, ]', "collapsedelimiters", false, ...
                    "delimitertype", "regularexpression")
          =>
          {
                      [1,1] = a
                      [1,2] =
                      [1,3] = b
                      [1,4] =
                      [1,5] = c
          }

          strsplit ("a,\t,b, c", {',', '\s'}, "delimitertype", "regularexpression")
          =>
          {
                      [1,1] = a
                      [1,2] = b
                      [1,3] = c
          }

          strsplit ("a,\t,b, c", {',', ' ', '\t'}, "collapsedelimiters", false)
          =>
          {
                      [1,1] = a
                      [1,2] =
                      [1,3] =
                      [1,4] = b
                      [1,5] =
                      [1,6] = c
          }

     ostrsplit, strjoin, strtok, regexp

 -- [CSTR] =: ostrsplit (S, SEP)
 -- [CSTR] =: ostrsplit (S, SEP, STRIP_EMPTY)
     Split the string S using one or more separators SEP and return a cell array of strings.

     Consecutive separators and separators at boundaries result in empty strings, unless STRIP_EMPTY is true.  The default value of STRIP_EMPTY is false.

     2-D character arrays are split at separators and at the original column boundaries.

     Example:

          ostrsplit ("a,b,c", ",")
                =>
                    {
                      [1,1] = a
                      [1,2] = b
                      [1,3] = c
                    }

          ostrsplit (["a,b" ; "cde"], ",")
                =>
                    {
                      [1,1] = a
                      [1,2] = b
                      [1,3] = cde
                    }

     strsplit, strtok

 -- STR =: strjoin (CSTR)
 -- STR =: strjoin (CSTR, DELIMITER)
     Join the elements of the cell string array, CSTR, into a single string.

     If no DELIMITER is specified, the elements of CSTR are separated by a space.

     If DELIMITER is specified as a string, the cell string array is joined using the string.  Escape sequences are supported.

     If DELIMITER is a cell string array whose length is one less than CSTR, then the elements of CSTR are joined by interleaving the cell string elements of DELIMITER.  Escape sequences are not supported.

          strjoin ({'Octave','Scilab','Lush','Yorick'}, '*')
                => 'Octave*Scilab*Lush*Yorick'

     strsplit

Searching in Strings
--------------------

Since a string is a character array, comparisons between strings work element by element as the following example shows:

     GNU = "GNU's Not UNIX";
     spaces = (GNU == " ")
          => spaces =
            0   0   0   0   0   1   0   0   0   1   0   0   0   0

To determine if two strings are identical it is necessary to use the strcmp function.  It compares complete strings and is case sensitive.  strncmp compares only the first N characters (with N given as a parameter).  strcmpi and strncmpi are the corresponding functions for case-insensitive comparison.

 -- TF =: strcmp (STR1, STR2)
     Return 1 if the character strings STR1 and STR2 are the same, and 0 otherwise.

     If either STR1 or STR2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.

     Caution: For compatibility with MATLAB, Octave's strcmp function returns 1 if the character strings are equal, and 0 otherwise. This is just the opposite of the corresponding C library function. strcmpi, strncmp, strncmpi

 -- TF =: strncmp (STR1, STR2, N)
     Return 1 if the first N characters of strings STR1 and STR2 are the same, and 0 otherwise.

          strncmp ("abce", "abcd", 3)
                => 1

     If either STR1 or STR2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.

          strncmp ("abce", {"abcd", "bca", "abc"}, 3)
               => [1, 0, 1]

     Caution: For compatibility with MATLAB, Octave's strncmp function returns 1 if the character strings are equal, and 0 otherwise. This is just the opposite of the corresponding C library function. strncmpi, strcmp, strcmpi

 -- TF =: strcmpi (STR1, STR2)
     Return 1 if the character strings STR1 and STR2 are the same, disregarding case of alphabetic characters, and 0 otherwise.

     If either STR1 or STR2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.

     Caution: For compatibility with MATLAB, Octave's strcmp function returns 1 if the character strings are equal, and 0 otherwise. This is just the opposite of the corresponding C library function.

     Caution: National alphabets are not supported. strcmp, strncmp, strncmpi

 -- TF =: strncmpi (STR1, STR2, N)
     Return 1 if the first N character of S1 and S2 are the same, disregarding case of alphabetic characters, and 0 otherwise.

     If either STR1 or STR2 is a cell array of strings, then an array of the same size is returned, containing the values described above for every member of the cell array.  The other argument may also be a cell array of strings (of the same size or with only one element), char matrix or character string.

     Caution: For compatibility with MATLAB, Octave's strncmpi function returns 1 if the character strings are equal, and 0 otherwise. This is just the opposite of the corresponding C library function.

     Caution: National alphabets are not supported. strncmp, strcmp, strcmpi

Despite those comparison functions, there are more specialized function to find the index position of a search pattern within a string.

 -- RETVAL =: startsWith (STR, PATTERN)
 -- RETVAL =: startsWith (STR, PATTERN, "IgnoreCase", IGNORE_CASE)
     Check whether string(s) start with pattern(s).

     Return an array of logical values that indicates which string(s) in the input STR (a single string or cell array of strings) begin with the input PATTERN (a single string or cell array of strings).

     If the value of the parameter "IgnoreCase" is true, then the function will ignore the letter case of STR and PATTERN.  By default, the comparison is case sensitive.

     Examples:

          ## one string and one pattern while considering case
          startsWith ("hello", "he")
                =>  1

          ## one string and one pattern while ignoring case
          startsWith ("hello", "HE", "IgnoreCase", true)
                =>  1

          ## multiple strings and multiple patterns while considering case
          startsWith ({"lab work.pptx", "data.txt", "foundations.ppt"},
                      {"lab", "data"})
                =>  1  1  0

          ## multiple strings and one pattern while considering case
          startsWith ({"DATASHEET.ods", "data.txt", "foundations.ppt"},
                      "data", "IgnoreCase", false)
                =>  0  1  0

          ## multiple strings and one pattern while ignoring case
          startsWith ({"DATASHEET.ods", "data.txt", "foundations.ppt"},
                      "data", "IgnoreCase", true)
                =>  1  1  0

     endsWith, regexp, strncmp, strncmpi

 -- RETVAL =: endsWith (STR, PATTERN)
 -- RETVAL =: endsWith (STR, PATTERN, "IgnoreCase", IGNORE_CASE)
     Check whether string(s) end with pattern(s).

     Return an array of logical values that indicates which string(s) in the input STR (a single string or cell array of strings) end with the input PATTERN (a single string or cell array of strings).

     If the value of the parameter "IgnoreCase" is true, then the function will ignore the letter case of STR and PATTERN.  By default, the comparison is case sensitive.

     Examples:

          ## one string and one pattern while considering case
          endsWith ("hello", "lo")
                =>  1

          ## one string and one pattern while ignoring case
          endsWith ("hello", "LO", "IgnoreCase", true)
                =>  1

          ## multiple strings and multiple patterns while considering case
          endsWith ({"tests.txt", "mydoc.odt", "myFunc.m", "results.pptx"},
                    {".docx", ".odt", ".txt"})
                =>  1  1  0  0

          ## multiple strings and one pattern while considering case
          endsWith ({"TESTS.TXT", "mydoc.odt", "result.txt", "myFunc.m"},
                    ".txt", "IgnoreCase", false)
                =>  0  0  1  0

          ## multiple strings and one pattern while ignoring case
          endsWith ({"TESTS.TXT", "mydoc.odt", "result.txt", "myFunc.m"},
                    ".txt", "IgnoreCase", true)
                =>  1  0  1  0

     startsWith, regexp, strncmp, strncmpi

 -- V =: findstr (S, T)
 -- V =: findstr (S, T, OVERLAP)

     This function is obsolete.  Use strfind instead.

     Return the vector of all positions in the longer of the two strings S and T where an occurrence of the shorter of the two starts.

     If the optional argument OVERLAP is true (default), the returned vector can include overlapping positions.  For example:

          findstr ("ababab", "a")
               => [1, 3, 5];
          findstr ("abababa", "aba", 0)
               => [1, 5]

     Caution: findstr is obsolete.  Use strfind in all new code. strfind, strmatch, strcmp, strncmp, strcmpi, strncmpi, find

 -- IDX =: strchr (STR, CHARS)
 -- IDX =: strchr (STR, CHARS, N)
 -- IDX =: strchr (STR, CHARS, N, DIRECTION)
 -- [I, J] =: strchr (...)
     Search through the string STR for occurrences of characters from the set CHARS.

     The return value(s), as well as the N and DIRECTION arguments behave identically as in find.

     This will be faster than using regexp in most cases.

     find

 -- N =: index (S, T)
 -- N =: index (S, T, DIRECTION)
     Return the position of the first occurrence of the string T in the string S, or 0 if no occurrence is found.

     S may also be a string array or cell array of strings.

     For example:

          index ("Teststring", "t")
              => 4

     If DIRECTION is "first", return the first element found. If DIRECTION is "last", return the last element found.

     find, rindex

 -- N =: rindex (S, T)
     Return the position of the last occurrence of the character string T in the character string S, or 0 if no occurrence is found.

     S may also be a string array or cell array of strings.

     For example:

          rindex ("Teststring", "t")
               => 6

     The rindex function is equivalent to index with DIRECTION set to "last".

     find, index

 -- IDX =: unicode_idx (STR)
     Return an array with the indices for each UTF-8 encoded character in STR.

          unicode_idx ("aäbc")
               => [1, 2, 2, 3, 4]

 -- IDX =: strfind (STR, PATTERN)
 -- IDX =: strfind (CELLSTR, PATTERN)
 -- IDX =: strfind (..., "overlaps", VAL)
 -- IDX =: strfind (..., "forcecelloutput", VAL)
     Search for PATTERN in the string STR and return the starting index of every such occurrence in the vector IDX.

     If there is no such occurrence, or if PATTERN is longer than STR, or if PATTERN itself is empty, then IDX is the empty array [].

     The optional argument "overlaps" determines whether the pattern can match at every position in STR (true), or only for unique occurrences of the complete pattern (false).  The default is true.

     If a cell array of strings CELLSTR is specified then IDX is a cell array of vectors, as specified above.

     The optional argument "forcecelloutput" forces IDX to be returned as a cell array of vectors.  The default is false.

     Examples:

          strfind ("abababa", "aba")
               => [1, 3, 5]

          strfind ("abababa", "aba", "overlaps", false)
               => [1, 5]

          strfind ({"abababa", "bebebe", "ab"}, "aba")
               =>
                  {
                    [1,1] =

                       1   3   5

                    [1,2] = [](1x0)
                    [1,3] = [](1x0)
                  }

          strfind ("abababa", "aba", "forcecelloutput", true)
               =>
                  {
                    [1,1] =

                       1   3   5
                  }

     regexp, regexpi, find

 -- IDX =: strmatch (S, A)
 -- IDX =: strmatch (S, A, "exact")

     This function is obsolete.  Use an alternative such as strncmp or strcmp instead.

     Return indices of entries of A which begin with the string S.

     The second argument A must be a string, character matrix, or a cell array of strings.

     If the third argument "exact" is not given, then S only needs to match A up to the length of S.  Trailing spaces and nulls in S and A are ignored when matching.

     For example:

          strmatch ("apple", "apple juice")
               => 1

          strmatch ("apple", ["apple  "; "apple juice"; "an apple"])
               => [1; 2]

          strmatch ("apple", ["apple  "; "apple juice"; "an apple"], "exact")
               => [1]

     Caution: strmatch is obsolete (and can produce incorrect results in MATLAB when used with cell arrays of strings.  Use strncmp (normal case) or strcmp ("exact" case) in all new code.  Other replacement possibilities, depending on application, include regexp or validatestring. strncmp, strcmp, regexp, strfind, validatestring

Searching and Replacing in Strings
----------------------------------

 -- NEWSTR =: strrep (STR, PTN, REP)
 -- NEWSTR =: strrep (CELLSTR, PTN, REP)
 -- NEWSTR =: strrep (..., "overlaps", VAL)
     Replace all occurrences of the pattern PTN in the string STR with the string REP and return the result.

     The optional argument "overlaps" determines whether the pattern can match at every position in STR (true), or only for unique occurrences of the complete pattern (false).  The default is true.

     S may also be a cell array of strings, in which case the replacement is done for each element and a cell array is returned.

     Example:

          strrep ("This is a test string", "is", "&%$")
              =>  "Th&%$ &%$ a test string"

     regexprep, strfind

 -- NEWSTR =: erase (STR, PTN)
     Delete all occurrences of PTN within STR.

     STR and PTN can be ordinary strings, cell array of strings, or character arrays.

     Examples

          ## string, single pattern
          erase ("Hello World!", " World")
              => "Hello!"

          ## cellstr, single pattern
          erase ({"Hello", "World!"}, "World")
              => {"Hello", "!"}

          ## string, multiple patterns
          erase ("The Octave interpreter is fabulous", ...
                 {"interpreter ", "The "})
              => "Octave is fabulous"

          ## cellstr, multiple patterns
          erase ({"The ", "Octave interpreter ", "is fabulous"}, ...
                 {"interpreter ", "The "})
              => {"", "Octave ", "is fabulous"}

     Programming Note: erase deletes the first instance of a pattern in a string when there are overlapping occurrences.  For example:

          erase ("abababa", "aba")
              => "b"

     For processing overlaps, see strrep.

     strrep, regexprep

 -- [S, E, TE, M, T, NM, SP] =: regexp (STR, PAT)
 -- [...] =: regexp (STR, PAT, "OPT1", ...)
     Regular expression string matching.

     Search for PAT in UTF-8 encoded STR and return the positions and substrings of any matches, or empty values if there are none.

     The matched pattern PAT can include any of the standard regex operators, including:

     .
          Match any character

     * + ? {}
          Repetition operators, representing

          *
               Match zero or more times

          +
               Match one or more times

          ?
               Match zero or one times

          {N}
               Match exactly N times

          {N,}
               Match N or more times

          {M,N}
               Match between M and N times

     [...] [^...]

          List operators.  The pattern will match any character listed between "[" and "]".  If the first character is "^" then the pattern is inverted and any character except those listed between brackets will match.

          Escape sequences defined below can also be used inside list operators.  For example, a template for a floating point number might be [-+.\d]+.

     () (?:)
          Grouping operator.  The first form, parentheses only, also creates a token.

     |
          Alternation operator.  Match one of a choice of regular expressions.  The alternatives must be delimited by the grouping operator () above.

     ^ $
          Anchoring operators.  Requires pattern to occur at the start (^) or end ($) of the string.

     In addition, the following escaped characters have special meaning.

     \d
          Match any digit

     \D
          Match any non-digit

     \s
          Match any whitespace character

     \S
          Match any non-whitespace character

     \w
          Match any word character

     \W
          Match any non-word character

     \<
          Match the beginning of a word

     \>
          Match the end of a word

     \B
          Match within a word

     Implementation Note: For compatibility with MATLAB, escape sequences in PAT (e.g., "\n" => newline) are expanded even when PAT has been defined with single quotes.  To disable expansion use a second backslash before the escape sequence (e.g., "\\n") or use the regexptranslate function.

     The outputs of regexp default to the order given below

     s
          The start indices of each matching substring

     e
          The end indices of each matching substring

     te
          The extents of each matched token surrounded by (...) in PAT

     m
          A cell array of the text of each match

     t
          A cell array of the text of each token matched

     nm
          A structure containing the text of each matched named token, with the name being used as the fieldname.  A named token is denoted by (?<name>...).

     sp
          A cell array of the text not returned by match, i.e., what remains if you split the string based on PAT.

     Particular output arguments, or the order of the output arguments, can be selected by additional OPT arguments.  These are strings and the correspondence between the output arguments and the optional argument are

       'start'          S
       'end'            E
       'tokenExtents'   TE
       'match'          M
       'tokens'         T
       'names'          NM
       'split'          SP

     Additional arguments are summarized below.

     once
          Return only the first occurrence of the pattern.

     matchcase
          Make the matching case sensitive.  (default)

          Alternatively, use (?-i) in the pattern.

     ignorecase
          Ignore case when matching the pattern to the string.

          Alternatively, use (?i) in the pattern.

     stringanchors
          Match the anchor characters at the beginning and end of the string. (default)

          Alternatively, use (?-m) in the pattern.

     lineanchors
          Match the anchor characters at the beginning and end of the line.

          Alternatively, use (?m) in the pattern.

     dotall
          The pattern . matches all characters including the newline character. (default)

          Alternatively, use (?s) in the pattern.

     dotexceptnewline
          The pattern . matches all characters except the newline character.

          Alternatively, use (?-s) in the pattern.

     literalspacing
          All characters in the pattern, including whitespace, are significant and are used in pattern matching.  (default)

          Alternatively, use (?-x) in the pattern.

     freespacing
          The pattern may include arbitrary whitespace and also comments beginning with the character #.

          Alternatively, use (?x) in the pattern.

     noemptymatch
          Zero-length matches are not returned.  (default)

     emptymatch
          Return zero-length matches.

          regexp ('a', 'b*', 'emptymatch') returns [1 2] because there are zero or more 'b' characters at positions 1 and end-of-string.

     Stack Limitation Note: Pattern searches are done with a recursive function which can overflow the program stack when there are a high number of matches. For example,

          regexp (repmat ('a', 1, 1e5), '(a)+')

     may lead to a segfault.  As an alternative, consider constructing pattern searches that reduce the number of matches (e.g., by creatively using set complement), and then further processing the return variables (now reduced in size) with successive regexp searches.

     Octave's regexp implementation is based on the Perl Compatible Regular Expressions library (https://www.pcre.org/).  For a more comprehensive list of regexp operator syntax see the "PCRE Syntax quick-reference summary".

     regexpi, strfind, regexprep

 -- [S, E, TE, M, T, NM, SP] =: regexpi (STR, PAT)
 -- [...] =: regexpi (STR, PAT, "OPT1", ...)

     Case insensitive regular expression string matching.

     Search for PAT in UTF-8 encoded STR and return the positions and substrings of any matches, or empty values if there are none. See regexp, for details on the syntax of the search pattern. regexp

 -- OUTSTR =: regexprep (STRING, PAT, REPSTR)
 -- OUTSTR =: regexprep (STRING, PAT, REPSTR, "OPT1", ...)
     Replace occurrences of pattern PAT in STRING with REPSTR.

     The pattern is a regular expression as documented for regexp. See regexp.

     All strings must be UTF-8 encoded.

     The replacement string may contain $i, which substitutes for the ith set of parentheses in the match string.  For example,

          regexprep ("Bill Dunn", '(\w+) (\w+)', '$2, $1')

     returns "Dunn, Bill"

     Options in addition to those of regexp are

     once
          Replace only the first occurrence of PAT in the result.

     warnings
          This option is present for compatibility but is ignored.

     Implementation Note: For compatibility with MATLAB, escape sequences in PAT (e.g., "\n" => newline) are expanded even when PAT has been defined with single quotes.  To disable expansion use a second backslash before the escape sequence (e.g., "\\n") or use the regexptranslate function. regexp, regexpi, strrep

 -- STR =: regexptranslate (OP, S)
     Translate a string for use in a regular expression.

     This may include either wildcard replacement or special character escaping.

     The behavior is controlled by OP which can take the following values

     "wildcard"
          The wildcard characters ., *, and ? are replaced with wildcards that are appropriate for a regular expression.  For example:

               regexptranslate ("wildcard", "*.m")
                    => '.*\.m'

     "escape"
          The characters $.?[], that have special meaning for regular expressions are escaped so that they are treated literally.  For example:

               regexptranslate ("escape", "12.5")
                    => '12\.5'

     regexp, regexpi, regexprep

Converting Strings
==================

Octave offers several kinds of conversion functions for Strings.

String encoding
---------------

 -- NATIVE_BYTES =: unicode2native (UTF8_STR, CODEPAGE)
 -- NATIVE_BYTES =: unicode2native (UTF8_STR)
     Convert UTF-8 string UTF8_STR to byte stream using CODEPAGE.

     The character vector UTF8_STR is converted to a byte stream NATIVE_BYTES using the code page given by CODEPAGE.  The string CODEPAGE must be an identifier of a valid code page. Examples for valid code pages are "ISO-8859-1", "Shift-JIS", or "UTF-16".  For a list of supported code pages, see https://www.gnu.org/software/libiconv.  If CODEPAGE is omitted or empty, the system default codepage is used.

     If any of the characters cannot be mapped into the codepage CODEPAGE, they are replaced with the appropriate substitution sequence for that codepage.

     native2unicode

 -- UTF8_STR =: native2unicode (NATIVE_BYTES, CODEPAGE)
 -- UTF8_STR =: native2unicode (NATIVE_BYTES)
     Convert byte stream NATIVE_BYTES to UTF-8 using CODEPAGE.

     The numbers in the vector NATIVE_BYTES are rounded and clipped to integers between 0 and 255.  This byte stream is then mapped into the code page given by the string CODEPAGE and returned in the string UTF8_STR.  Octave uses UTF-8 as its internal encoding.  The string CODEPAGE must be an identifier of a valid code page.  Examples for valid code pages are "ISO-8859-1", "Shift-JIS", or "UTF-16".  For a list of supported code pages, see https://www.gnu.org/software/libiconv.  If CODEPAGE is omitted or empty, the system default codepage is used.

     If NATIVE_BYTES is a string vector, it is returned as is.

     unicode2native

Numerical Data and Strings
--------------------------

Apart from the string concatenation functions (see Concatenating Strings) which cast numerical data to the corresponding UTF-8 encoded characters, there are several functions that format numerical data as strings.  mat2str and num2str convert real or complex matrices, while int2str converts integer matrices.  int2str takes the real part of complex values and round fractional values to integer.  A more flexible way to format numerical data as strings is the sprintf function (see Formatted Output, sprintf).

 -- S =: mat2str (X, N)
 -- S =: mat2str (X, N, "class")
     Format real, complex, and logical matrices as strings.

     The returned string may be used to reconstruct the original matrix by using the eval function.

     The precision of the values is given by N.  If N is a scalar then both real and imaginary parts of the matrix are printed to the same precision.  Otherwise N(1) defines the precision of the real part and N(2) defines the precision of the imaginary part. The default for N is 15.

     If the argument "class" is given then the class of X is included in the string in such a way that eval will result in the construction of a matrix of the same class.

          mat2str ([ -1/3 + i/7; 1/3 - i/7 ], [4 2])
               => "[-0.3333+0.14i;0.3333-0.14i]"

          mat2str ([ -1/3 +i/7; 1/3 -i/7 ], [4 2])
               => "[-0.3333+0i 0+0.14i;0.3333+0i -0-0.14i]"

          mat2str (int16 ([1 -1]), "class")
               => "int16([1 -1])"

          mat2str (logical (eye (2)))
               => "[true false;false true]"

          isequal (x, eval (mat2str (x)))
               => 1

     sprintf, num2str, int2str

 -- STR =: num2str (X)
 -- STR =: num2str (X, PRECISION)
 -- STR =: num2str (X, FORMAT)
     Convert a number (or array) to a string (or a character array).

     The optional second argument may either give the number of significant digits (PRECISION) to be used in the output or a format template string (FORMAT) as in sprintf (see Formatted Output). num2str can also process complex numbers.

     Examples:

          num2str (123.456)
            => 123.456

          num2str (123.456, 4)
            => 123.5

          s = num2str ([1, 1.34; 3, 3.56], "%5.1f")
            => s =
                 1.0  1.3
                 3.0  3.6
          whos s
            => Variables in the current scope:
                  Attr Name        Size                     Bytes  Class
                  ==== ====        ====                     =====  =====
                       s           2x8                         16  char
               Total is 16 elements using 16 bytes

          num2str (1.234 + 27.3i)
            => 1.234+27.3i

     The num2str function is not very flexible.  For better control over the results, use sprintf (see Formatted Output).

     Programming Notes:

     For MATLAB compatibility, leading spaces are stripped before returning the string.

     Integers larger than flintmax may not be displayed correctly.

     For complex X, the format string may only contain one output conversion specification and nothing else.  Otherwise, results will be unpredictable.

     Any optional FORMAT specified by the programmer is used without modification.  This is in contrast to MATLAB which tampers with the FORMAT based on internal heuristics. sprintf, int2str, mat2str

 -- STR =: int2str (N)
     Convert an integer (or array of integers) to a string (or a character array).

          int2str (123)
            => 123

          s = int2str ([1, 2, 3; 4, 5, 6])
            => s =
                  1  2  3
                  4  5  6

          whos s
            => Variables in the current scope:
                  Attr Name        Size                     Bytes  Class
                  ==== ====        ====                     =====  =====
                       s           2x7                         14  char
               Total is 14 elements using 14 bytes

     This function is not very flexible.  For better control over the results, use sprintf (see Formatted Output).

     Programming Notes:

     Non-integers are rounded to integers before display.  Only the real part of complex numbers is displayed.

     sprintf, num2str, mat2str

 -- D =: str2double (STR)
     Convert a string to a real or complex number.

     The string must be in one of the following formats where a and b are real numbers and the complex unit is 'i' or 'j':

       * a + bi

       * a + b*i

       * a + i*b

       * bi + a

       * b*i + a

       * i*b + a

     If present, a and/or b are of the form [+-]d[,.]d[[eE][+-]d] where the brackets indicate optional arguments and 'd' indicates zero or more digits.  The special input values Inf, NaN, and NA are also accepted.

     STR may be a character string, character matrix, or cell array.  For character arrays the conversion is repeated for every row, and a double or complex array is returned.  Empty rows in S are deleted and not returned in the numeric array.  For cell arrays each character string element is processed and a double or complex array of the same dimensions as STR is returned.

     For unconvertible scalar or character string input str2double returns a NaN.  Similarly, for character array input str2double returns a NaN for any row of S that could not be converted.  For a cell array, str2double returns a NaN for any element of S for which conversion fails.  Note that numeric elements in a mixed string/numeric cell array are not strings and the conversion will fail for these elements and return NaN.

     Programming Note: str2double can replace str2num, is more efficient, and avoids the security risk of using eval on unknown data. str2num

 -- X =: str2num (S)
 -- [X, STATE] =: str2num (S)
     Convert the string (or character array) S to a number (or an array).

     Examples:

          str2num ("3.141596")
                => 3.141596

          str2num (["1, 2, 3"; "4, 5, 6"])
                => 1  2  3
                   4  5  6

     The optional second output, STATE, is logically true when the conversion is successful.  If the conversion fails the numeric output, X, is empty and STATE is false.

     Caution: As str2num uses the eval function to do the conversion, str2num will execute any code contained in the string S.  Use str2double for a safer and faster conversion.

     For cell array of strings use str2double. str2double, eval

 -- D =: bin2dec (STR)
     Return the decimal number corresponding to the binary number represented by the string STR.

     For example:

          bin2dec ("1110")
               => 14

     Spaces are ignored during conversion and may be used to make the binary number more readable.

          bin2dec ("1000 0001")
               => 129

     If STR is a string matrix, return a column vector with one converted number per row of STR; Invalid rows evaluate to NaN.

     If STR is a cell array of strings, return a column vector with one converted number per cell element in STR. dec2bin, base2dec, hex2dec

 -- BSTR =: dec2bin (D)
 -- BSTR =: dec2bin (D, LEN)
     Return a string of ones and zeros representing the conversion of the integer D to a binary number.

     If D is a matrix or cell array, return a string matrix with one row for each element in D, padded with leading zeros to the width of the largest value.

     The optional second argument, LEN, specifies the minimum number of digits in the result.

     For negative elements of D, return the binary value of the two's complement.  The result is padded with leading ones to 8, 16, 32, or 64 bits as appropriate for the magnitude of the input.  Positive input elements are padded with leading zeros to the same width.

     Examples:

          dec2bin (14)
               => "1110"

          dec2bin (-14)
               => "11110010"

     Programming tip: dec2bin discards any fractional part of the input. If you need the fractional part to be converted too, call dec2base with a nonzero number of decimal places.  You can also use fix or round on fractional inputs to ensure predictable rounding behavior.

     bin2dec, dec2base, dec2hex

 -- HSTR =: dec2hex (D)
 -- HSTR =: dec2hex (D, LEN)
     Return a string representing the conversion of the integer D to a hexadecimal (base16) number.

     If D is negative, return the hexadecimal complement of D.

     If D is a matrix or cell array, return a string matrix with one row for each element in D, padded with leading zeros to the width of the largest value.

     The optional second argument, LEN, specifies the minimum number of digits in the result.

     Examples:

          dec2hex (2748)
               => "ABC"

          dec2hex (-2)
               => "FE"

     Programming tip: dec2hex discards any fractional part of the input. If you need the fractional part to be converted too, call dec2base with a nonzero number of decimal places.  You can also use fix or round on fractional inputs to ensure predictable rounding behavior.

     hex2dec, dec2base, dec2bin

 -- D =: hex2dec (STR)
     Return the integer corresponding to the hexadecimal number represented by the string STR.

     For example:

          hex2dec ("12B")
                => 299
          hex2dec ("12b")
                => 299

     If STR is a string matrix, return a column vector with one converted number per row of STR; Invalid rows evaluate to NaN.

     If STR is a cell array of strings, return a column vector with one converted number per cell element in STR.

     dec2hex, base2dec, bin2dec

 -- STR =: dec2base (D, BASE)
 -- STR =: dec2base (D, BASE, LEN)
 -- STR =: dec2base (D, BASE, LEN, DECIMALS)
     Return a string of symbols in base BASE corresponding to the value D.

          dec2base (123, 3)
             => "11120"

     If D is negative, then the result will represent D in complement notation.  For example, negative binary numbers are in twos-complement, and analogously for other bases.

     If D is a matrix or cell array, return a string matrix with one row per element in D, padded with leading zeros to the width of the largest value.

     If BASE is a string then the characters of BASE are used as the symbols for the digits of D.  Whitespace (spaces, tabs, newlines, , etc.) may not be used as a symbol.

          dec2base (123, "aei")
             => "eeeia"

     The optional third argument, LEN, specifies the minimum number of digits in the integer part of the result.  If this is omitted, then dec2base uses enough digits to accommodate the input.

     The optional fourth argument, DECIMALS, specifies the number of digits to represent the fractional part of the input.  If this is omitted, then it is set to zero, and dec2base returns an integer output for backward compatibility.

          dec2base (100*pi, 16)
          => "13A"
          dec2base (100*pi, 16, 4)
          => "013A"
          dec2base (100*pi, 16, 4, 6)
          => "013A.28C59D"
          dec2base (-100*pi, 16)
          => "EC6"
          dec2base (-100*pi, 16, 4)
          => "FEC6"
          dec2base (-100*pi, 16, 4, 6)
          => "FEC5.D73A63"

     Programming tip: When passing negative inputs to dec2base, it is best to explicitly specify the length of the output required.

     base2dec, dec2bin, dec2hex

 -- D =: base2dec (STR, BASE)
     Convert STR from a string of digits in base BASE to a decimal integer (base 10).

          base2dec ("11120", 3)
             => 123

     If STR is a string matrix, return a column vector with one value per row of STR.  If a row contains invalid symbols then the corresponding value will be NaN.

     If STR is a cell array of strings, return a column vector with one value per cell element in STR.

     If BASE is a string, the characters of BASE are used as the symbols for the digits of STR.  Space (' ') may not be used as a symbol.

          base2dec ("yyyzx", "xyz")
             => 123

     dec2base, bin2dec, hex2dec

 -- S =: num2hex (N)
 -- S =: num2hex (N, "cell")
     Convert a numeric array to an array of hexadecimal strings.

     For example:

          num2hex ([-1, 1, e, Inf])
          => "bff0000000000000
              3ff0000000000000
              4005bf0a8b145769
              7ff0000000000000"

     If the argument N is a single precision number or vector, the returned string has a length of 8.  For example:

          num2hex (single ([-1, 1, e, Inf]))
          => "bf800000
              3f800000
              402df854
              7f800000"

     With the optional second argument "cell", return a cell array of strings instead of a character array. hex2num, hex2dec, dec2hex

 -- N =: hex2num (S)
 -- N =: hex2num (S, CLASS)
     Typecast a hexadecimal character array or cell array of strings to an array of numbers.

     By default, the input array is interpreted as a hexadecimal number representing a double precision value.  If fewer than 16 characters are given the strings are right padded with '0' characters.

     Given a string matrix, hex2num treats each row as a separate number.

          hex2num (["4005bf0a8b145769"; "4024000000000000"])
             => [2.7183; 10.000]

     The optional second argument CLASS may be used to cause the input array to be interpreted as a different value type.  Possible values are

     Option   Characters
     "int8"   2
     "uint8"   2
     "int16"   4
     "uint16"   4
     "int32"   8
     "uint32"   8
     "int64"   16
     "uint64"   16
     "char"   2
     "single"   8
     "double"   16

     For example:

          hex2num (["402df854"; "41200000"], "single")
             => [2.7183; 10.000]

     num2hex, hex2dec, dec2hex

 -- [A, ...] =: strread (STR)
 -- [A, ...] =: strread (STR, FORMAT)
 -- [A, ...] =: strread (STR, FORMAT, FORMAT_REPEAT)
 -- [A, ...] =: strread (STR, FORMAT, PROP1, VALUE1, ...)
 -- [A, ...] =: strread (STR, FORMAT, FORMAT_REPEAT, PROP1, VALUE1, ...)

     This function is obsolete.  Use textscan instead.

     Read data from a string.

     The string STR is split into words that are repeatedly matched to the specifiers in FORMAT.  The first word is matched to the first specifier, the second to the second specifier and so forth.  If there are more words than specifiers, the process is repeated until all words have been processed.

     The string FORMAT describes how the words in STR should be parsed.  It may contain any combination of the following specifiers:

     %s
          The word is parsed as a string.

     %f
     %n
          The word is parsed as a number and converted to double.

     %d
     %u
          The word is parsed as a number and converted to int32.

     %*
     %*f
     %*s
          The word is skipped.

          For %s and %d, %f, %n, %u and the associated %*s ... specifiers an optional width can be specified as %Ns, etc. where N is an integer > 1. For %f, format specifiers like %N.Mf are allowed.

     literals
          In addition the format may contain literal character strings; these will be skipped during reading.

     Parsed word corresponding to the first specifier are returned in the first output argument and likewise for the rest of the specifiers.

     By default, FORMAT is "%f", meaning that numbers are read from STR.  This will do if STR contains only numeric fields.

     For example, the string

          STR = "\
          Bunny Bugs   5.5\n\
          Duck Daffy  -7.5e-5\n\
          Penguin Tux   6"

     can be read using

          [A, B, C] = strread (STR, "%s %s %f");

     Optional numeric argument FORMAT_REPEAT can be used for limiting the number of items read:

     -1
          (default) read all of the string until the end.

     N
          Read N times NARGOUT items.  0 (zero) is an acceptable value for FORMAT_REPEAT.

     The behavior of strread can be changed via property-value pairs.  The following properties are recognized:

     "commentstyle"
          Parts of STR are considered comments and will be skipped. VALUE is the comment style and can be any of the following.

            * "shell" Everything from # characters to the nearest end-of-line is skipped.

            * "c" Everything between /* and */ is skipped.

            * "c++" Everything from // characters to the nearest end-of-line is skipped.

            * "matlab" Everything from % characters to the nearest end-of-line is skipped.

            * user-supplied.  Two options: (1) One string, or 1x1 cell string: Skip everything to the right of it; (2) 2x1 cell string array: Everything between the left and right strings is skipped.

     "delimiter"
          Any character in VALUE will be used to split STR into words (default value = any whitespace).  Note that whitespace is implicitly added to the set of delimiter characters unless a "%s" format conversion specifier is supplied; see "whitespace" parameter below.  The set of delimiter characters cannot be empty; if needed Octave substitutes a space as delimiter.

     "emptyvalue"
          Value to return for empty numeric values in non-whitespace delimited data. The default is NaN.  When the data type does not support NaN (int32 for example), then default is zero.

     "multipledelimsasone"
          Treat a series of consecutive delimiters, without whitespace in between, as a single delimiter.  Consecutive delimiter series need not be vertically "aligned".

     "treatasempty"
          Treat single occurrences (surrounded by delimiters or whitespace) of the string(s) in VALUE as missing values.

     "returnonerror"
          If VALUE true (1, default), ignore read errors and return normally. If false (0), return an error.

     "whitespace"
          Any character in VALUE will be interpreted as whitespace and trimmed; the string defining whitespace must be enclosed in double quotes for proper processing of special characters like "\t".  In each data field, multiple consecutive whitespace characters are collapsed into one space and leading and trailing whitespace is removed.  The default value for whitespace is " \b\r\n\t" (note the space).  Whitespace is always added to the set of delimiter characters unless at least one "%s" format conversion specifier is supplied; in that case only whitespace explicitly specified in "delimiter" is retained as delimiter and removed from the set of whitespace characters.  If whitespace characters are to be kept as-is (in e.g., strings), specify an empty value (i.e., "") for "whitespace"; obviously, whitespace cannot be a delimiter then.

     When the number of words in STR doesn't match an exact multiple of the number of format conversion specifiers, strread's behavior depends on the last character of STR:

     last character = "\n"
          Data columns are padded with empty fields or NaN so that all columns have equal length

     last character is not "\n"
          Data columns are not padded; strread returns columns of unequal length

     textscan, sscanf

JSON data encoding/decoding
---------------------------

JavaScript Object Notation, in short JSON, is a very common human readable and structured data format.  GNU Octave supports encoding and decoding this format with the following two functions.

 -- JSON_TXT =: jsonencode (OBJECT)
 -- JSON_TXT =: jsonencode (..., "ConvertInfAndNaN", TF)
 -- JSON_TXT =: jsonencode (..., "PrettyPrint", TF)

     Encode Octave data types into JSON text.

     The input OBJECT is an Octave variable to encode.

     The output JSON_TXT is the JSON text that contains the result of encoding OBJECT.

     If the value of the option "ConvertInfAndNaN" is true then NaN, NA, -Inf, and Inf values will be converted to "null" in the output.  If it is false then they will remain as their original values.  The default value for this option is true.

     If the value of the option "PrettyPrint" is true, the output text will have indentations and line feeds.  If it is false, the output will be condensed and written without whitespace.  The default value for this option is false.

     Programming Notes:

       * Complex numbers are not supported.

       * classdef objects are first converted to structs and then encoded.

       * To preserve escape characters (e.g., "\n"), use single-quoted strings.

       * Every character after the null character ("\0") in a double-quoted string will be dropped during encoding.

       * Encoding and decoding an array is not guaranteed to preserve the dimensions of the array.  In particular, row vectors will be reshaped to column vectors.

       * Encoding and decoding is not guaranteed to preserve the Octave data type because JSON supports fewer data types than Octave.  For example, if you encode an int8 and then decode it, you will get a double.

     This table shows the conversions from Octave data types to JSON data types:

     Octave data type   JSON data type
     logical scalar   Boolean
     logical vector   Array of Boolean, reshaped to row vector
     logical array    nested Array of Boolean
     numeric scalar   Number
     numeric vector   Array of Number, reshaped to row vector
     numeric array    nested Array of Number
     NaN, NA, Inf, -Inf

     when "ConvertInfAndNaN" = true   "null"
     NaN, NA, Inf, -Inf

     when "ConvertInfAndNaN" = false   "NaN", "NaN",
     "Infinity", "-Infinity"
     empty array      "[]"
     character vector   String
     character array   Array of String
     empty character array   ""
     cell scalar   Array
     cell vector   Array, reshaped to row vector
     cell array   Array, flattened to row vector
     struct scalar   Object
     struct vector   Array of Object, reshaped to row vector
     struct array    nested Array of Object
     classdef object   Object

     Examples:

          jsonencode ([1, NaN; 3, 4])
          => [[1,null],[3,4]]

          jsonencode ([1, NaN; 3, 4], "ConvertInfAndNaN", false)
          => [[1,NaN],[3,4]]

          ## Escape characters inside a single-quoted string
          jsonencode ('\0\a\b\t\n\v\f\r')
          => "\\0\\a\\b\\t\\n\\v\\f\\r"

          ## Escape characters inside a double-quoted string
          jsonencode ("\a\b\t\n\v\f\r")
          => "\u0007\b\t\n\u000B\f\r"

          jsonencode ([true; false], "PrettyPrint", true)
          => ans = [
               true,
               false
             ]

          jsonencode (['foo', 'bar'; 'foo', 'bar'])
          => ["foobar","foobar"]

          jsonencode (struct ('a', Inf, 'b', [], 'c', struct ()))
          => {"a":null,"b":[],"c":{}}

          jsonencode (struct ('structarray', struct ('a', {1; 3}, 'b', {2; 4})))
          => {"structarray":[{"a":1,"b":2},{"a":3,"b":4}]}

          jsonencode ({'foo'; 'bar'; {'foo'; 'bar'}})
          => ["foo","bar",["foo","bar"]]

          jsonencode (containers.Map({'foo'; 'bar'; 'baz'}, [1, 2, 3]))
          => {"bar":2,"baz":3,"foo":1}

     jsondecode

 -- OBJECT =: jsondecode (JSON_TXT)
 -- OBJECT =: jsondecode (..., "ReplacementStyle", RS)
 -- OBJECT =: jsondecode (..., "Prefix", PFX)
 -- OBJECT =: jsondecode (..., "makeValidName", TF)

     Decode text that is formatted in JSON.

     The input JSON_TXT is a string that contains JSON text.

     The output OBJECT is an Octave object that contains the result of decoding JSON_TXT.

     For more information about the options "ReplacementStyle" and "Prefix", see matlab.lang.makeValidName.

     If the value of the option "makeValidName" is false then names will not be changed by matlab.lang.makeValidName and the "ReplacementStyle" and "Prefix" options will be ignored.

     NOTE: Decoding and encoding JSON text is not guaranteed to reproduce the original text as some names may be changed by matlab.lang.makeValidName.

     This table shows the conversions from JSON data types to Octave data types:

     JSON data type   Octave data type
     Boolean   scalar logical
     Number   scalar double
     String   vector of characters
     Object   scalar struct (field names of the struct may be different from the keys of the JSON object due to matlab_lang_makeValidName
     null, inside a numeric array   NaN
     null, inside a non-numeric array   empty double array []
     Array, of different data types   cell array
     Array, of Booleans   logical array
     Array, of Numbers   double array
     Array, of Strings   cell array of character vectors (cellstr)
     Array of Objects, same field names   struct array
     Array of Objects, different field names   cell array of scalar structs

     Examples:

          jsondecode ('[1, 2, null, 3]')
              => ans =

                1
                2
              NaN
                3

          jsondecode ('["foo", "bar", ["foo", "bar"]]')
              => ans =
                 {
                   [1,1] = foo
                   [2,1] = bar
                   [3,1] =
                   {
                     [1,1] = foo
                     [2,1] = bar
                   }

                 }

          jsondecode ('{"nu#m#ber": 7, "s#tr#ing": "hi"}', ...
                      'ReplacementStyle', 'delete')
              => scalar structure containing the fields:

                   number = 7
                   string = hi

          jsondecode ('{"nu#m#ber": 7, "s#tr#ing": "hi"}', ...
                      'makeValidName', false)
              => scalar structure containing the fields:

                   nu#m#ber = 7
                   s#tr#ing = hi

          jsondecode ('{"1": "one", "2": "two"}', 'Prefix', 'm_')
              => scalar structure containing the fields:

                   m_1 = one
                   m_2 = two

     jsonencode, matlab.lang.makeValidName

Character Class Functions
=========================

Octave also provides the following character class test functions patterned after the functions in the standard C library.  They all operate on string arrays and return matrices of zeros and ones. Elements that are nonzero indicate that the condition was true for the corresponding character in the string array.  For example:

     isalpha ("!Q@WERT^Y&")
          => [ 0, 1, 0, 1, 1, 1, 1, 0, 1, 0 ]

 -- TF =: isalnum (S)
     Return a logical array which is true where the elements of S are letters or digits and false where they are not.

     This is equivalent to (isalpha (S) | isdigit (S)). isalpha, isdigit, ispunct, isspace, iscntrl

 -- TF =: isalpha (S)
     Return a logical array which is true where the elements of S are letters and false where they are not.

     This is equivalent to (islower (S) | isupper (S)). isdigit, ispunct, isspace, iscntrl, isalnum, islower, isupper

 -- TF =: isletter (S)
     Return a logical array which is true where the elements of S are letters and false where they are not.

     This is an alias for the isalpha function. isalpha, isdigit, ispunct, isspace, iscntrl, isalnum

 -- TF =: islower (S)
     Return a logical array which is true where the elements of S are lowercase letters and false where they are not. isupper, isalpha, isletter, isalnum

 -- TF =: isupper (S)
     Return a logical array which is true where the elements of S are uppercase letters and false where they are not. islower, isalpha, isletter, isalnum

 -- TF =: isdigit (S)
     Return a logical array which is true where the elements of S are decimal digits (0-9) and false where they are not. isxdigit, isalpha, isletter, ispunct, isspace, iscntrl

 -- TF =: isxdigit (S)
     Return a logical array which is true where the elements of S are hexadecimal digits (0-9 and a-fA-F). isdigit

 -- TF =: ispunct (S)
     Return a logical array which is true where the elements of S are punctuation characters and false where they are not. isalpha, isdigit, isspace, iscntrl

 -- TF =: isspace (S)
     Return a logical array which is true where the elements of S are whitespace characters (space, formfeed, newline, carriage return, tab, and vertical tab) and false where they are not. iscntrl, ispunct, isalpha, isdigit

 -- TF =: iscntrl (S)
     Return a logical array which is true where the elements of S are control characters and false where they are not. ispunct, isspace, isalpha, isdigit

 -- TF =: isgraph (S)
     Return a logical array which is true where the elements of S are printable characters (but not the space character) and false where they are not. isprint

 -- TF =: isprint (S)
     Return a logical array which is true where the elements of S are printable characters (including the space character) and false where they are not. isgraph

 -- TF =: isascii (S)
     Return a logical array which is true where the elements of S are ASCII characters (in the range 0 to 127 decimal) and false where they are not.

 -- TF =: isstrprop (STR, PROP)
 -- TF =: isstrprop (STR, PROP, 'ForceCellOutput', FLAG)
     Test character string properties.

     For example:

          isstrprop ("abc123", "alpha")
          => [1, 1, 1, 0, 0, 0]

     If STR is a cell array, isstrpop is applied recursively to each element of the cell array.

     Numeric arrays are converted to character strings.

     The second argument PROP must be one of

     "alpha"
          True for characters that are alphabetic (letters).

     "alnum"
     "alphanum"
          True for characters that are alphabetic or digits.

     "lower"
          True for lowercase letters.

     "upper"
          True for uppercase letters.

     "digit"
          True for decimal digits (0-9).

     "xdigit"
          True for hexadecimal digits (a-fA-F0-9).

     "space"
     "wspace"
          True for whitespace characters (space, formfeed, newline, carriage return, tab, vertical tab).

     "punct"
          True for punctuation characters (printing characters except space or letter or digit).

     "cntrl"
          True for control characters.

     "graph"
     "graphic"
          True for printing characters except space.

     "print"
          True for printing characters including space.

     "ascii"
          True for characters that are in the range of ASCII encoding.

     If the option 'ForceCellOutput' is given and FLAG is true then a cell value is returned rather than a logical array.

     isalpha, isalnum, islower, isupper, isdigit, isxdigit, isspace, ispunct, iscntrl, isgraph, isprint, isascii