classdef str
% STR - Class for Character Arrays
%
% Create a new type called STR with a character array inside, implemented as a structure.
% It was inspired in Visual Basic syntax.
% It was implemented many operators and functions overloads, but allows any character
% array function using ' conversor function, operator that was overloaded.
% It's necessary to create a folder from a MatLab folder in one of the MatLab paths. The
% folder name is class name, with @ prefix. The .m name is class name.
%
% Function and Operator list
% @@@@@@@@@@@@@@@@@@@@@@@@@@
%
% Operator Overload
% ==================
% ==,~=,<=,>=,>,< - Compare strings
% () - Access individual characters from a string (left or righ assignment side)
% ' (unary) - Convert for character array type, for using in any character array function
% not explicitaly overloaded here
% [], + - Concatenate strings
% - - Take away substrings from strings
% * - Repeat strings
% | - String concatenation with line feed (#10) character.
% \,/ - Find string in another string
%
%
% Conversion
% ===========
% .s - Access field from strutucture STR. It's best to use "char" function instead
% str - Convert character array in STR type.
% Also format number in STR with size, decimals and orientation (left, rigth or center)
% char - Convert STR type in character array (Overload)
% Function Overload
% =================
% disp - show string content
% length - length of a string
% upper - convert to uppercase
% lower - convert to lowercase
% strfind - seach string in another return all matches
% Get part of the string
% ======================
% left - return first specified characters from a string
% right - return last specified characters from a string
% mid - return mid specified character from a string
%
% Trimming blanks
% ================
% trim - Trim spaces in the end and in the beginning. Uses strtrim.
% rtrim - Trim spaces in the end
% ltrim - Trim spaces in the beginning
%
% Strings in fixed size field
% ===========================
% padl - put a string in a left of a specified length
% padr - put a string in a right of a specified length
% padc - put a string in a center of a specified length
%
% Miscelaneous functions
% ======================
% instr - search string in another return a scalar of firt occurrente. Accept initial position and
% accept ignore case
% repeat - repeat a string for a specified number of times
% replace - Change all occurrences from a old piece in a target for a new piece
% lt,gt,ge,le,eq,ne - comparison, with ignore case option
%
% Example
% @@@@@@@
% s1=str('paul')
% s2=str('richard')
% money=2.3
% if s1<=s2
% disp(s1+' and '+s2 + ' has US$ ' + str(money,1,2,'L') + ' MM' )
% else
% disp(s2+' and '+s1 + ' has US$ ' + str(money,1,2,'L') + ' MM' )
% end
properties
s
end
% Class methods
methods
%*****************************************************************************************
%* Str
%* Construct a Str object with a character array as its contents or format number as
%* Str type.
%*
%* Syntax: str(C [Size Desc Jusif ] )
%* C - Character array or Str or number
%* Len - Size of the field, if number. When number is wider, ignores it.
%* Decs - Number of decimal digits, if number
%* Justif - Justification to left, center or right ('L','R','C') Default: 'R'(Right)
%*
%* For testing STR type use
%* isa(v,'str')
%*
%* Example 1: (It can be used in any context, including expressions and functions calls)
%* a = str('try this one') % Create A, a STR type variable that encapsulates character array
%* a=
%* try this one
%*
%* Example 2:
%* ['The amount is ' Str(1200,1,2) ]
%* ans=
%* The amount is 1200.00
%******************************************************************************************
function obj = str(c,varargin)
if isa(c,'str')
obj.s = c.s;
elseif ischar(c)
obj.s = c;
else
n = size(varargin,2); % Number of variable arguments
len=1;
deci=0;
vet=3; % Default: right justification
if n>0
ch=varargin{n}; % The last one
len=varargin{1}; % field size of number
if ischar(ch) % last argument is char?
vet=strfind('LCR',upper(ch));
if isempty(vet), vet=3; else vet=vet(1); end
n=n-1;
end
if n==2, deci=varargin{2}; end % number of decimal point digits
end
obj = padcommon(c,vet,len,deci);
end
end % str
%*****************************************************************************************
%* CTranspose (Overload for unary operator "'")
%* Convert to char type, using the transpose operator
%* It can be used to work easily with STR type in many functions with no explicit overload.
%*
%* Example: How use sse regular expression functions like "regexp" in STR types
%*
%* a=str('Brazil is a big Country');
%* regexp(a','[A-Z]') % regexp(a,'[A-Z]') returns a error
%* ans =
%* 1 17
%*****************************************************************************************
function ret=ctranspose(s)
ret= char(s);
end
%*****************************************************************************************
%* or (Overload for operator "|")
%* Return concatenation with line feed inbetween.
%*
%* Syntax: A | B
%* A, B - input strings
%*
%* Example:
%* a = str('New York');
%* a | 'London'
%* ans =
%* New York
%* London
%*****************************************************************************************
function ret=or(a,b)
ret= str([char(a) char(10) char(b)]);
end
%*************************************************************************
%* padc
%* Put a string A in the center. Field width is LEN
%*
%* Syntax: padc(A, Len, [Caract] )
%* A - String
%* Len - size to center justification
%* Caract - caract to fill the padding. Default: space
%*
%* Example:
%* padc( str(' Character Array '),50,'=')
%* ans =
%* ====== Character Array =======
%**************************************************************************
function r=padc(a,len,caract)
if nargin<3, caract=' '; end
r = padcommon(a,2,len,caract);
end
%*****************************************************************************
%* padr
%* Justify a string A in the right. Field width is LEN
%*
%* Syntax: padr(A, Len, [Caract] )
%* A - String
%* Len - size to right justification
%* Caract - caract to fill the padding. Default: space
%*
%*****************************************************************************
function r=padr(a,len,caract)
if nargin<3, caract=' '; end
r = padcommon(a,3,len,caract);
end
%**************************************************************************
%* padl
%* Put a string A in the left. Field width is LEN
%*
%* Syntax: padl(A, Len, [Caract] )
%* A - String
%* Len - size to left justification
%* Caract - caract to fill the padding. Default: space
%*************************************************************************
function r=padl(a,len,caract)
if nargin<3, caract=' '; end
r = padcommon(a,1,len,caract);
end
%*************************************************************************
%* trim
%* Delete spaces in the begin and in the end of a string
%*
%* Syntax: trim(A)
%* A - String before its left and right spaces to be trimmed
%*************************************************************************
function r=trim(a)
r = str(strtrim(a.s));
end
%*****************************************************************
%* ltrim
%* Delete spaces in the begin of a string
%*
%* Syntax: ltrim(A)
%* A - String before its left spaces to be trimmed
%*****************************************************************
function r=ltrim(a)
a=char(a);
ind = find(~ isspace(a),1);
if isempty(ind)
r = str('');
else
r = str(a(ind:end));
end
end
%*****************************************************************
%* rtrim
%* Delete spaces in the end of a string
%*
%* Syntax: rtrim(A)
%* A - String before its right spaces to be trimmed
%*****************************************************************
function r=rtrim(a)
a=char(a);
ind = find(~ isspace(a),1,'last');
if isempty(ind)
r = str('');
else
r = str(a(1:ind));
end
end
%*****************************************************************
%* upper
%* Convert lowercase in uppercase
%*
%* Syntax: upper(A)
%* A - String
%*****************************************************************
function r=upper(a)
r = str(upper(a.s));
end
%*****************************************************************
%* lower
%* Converte uppercase in lowercase
%*
%* Syntax: lower(A)
%* A - String
%*****************************************************************
function r=lower(a)
r = str(lower(a.s));
end
%*****************************************************************
%* strfind
%* Search B in A e returns array with matching indexes
%*
%* Syntax: strfind(A,B, [IgnCase])
%* A - String target of the search
%* B - String to be searched in the target
%* IgnCase - true if ignores case (default false)
%*
%* Example:
%* strfind(str('Mary has a Mouse'),'m',true)
%* ans=
%* 1 12
%*****************************************************************
function r=strfind(a,b,igncase)
if nargin<3, igncase =false; end
if igncase
r=strfind(upper(char(a)),upper(char(b)));
else
r=strfind(char(a),char(b));
end
end
%**************************************************************************
%* instr
%* Search B in A since position POSI. if IGNCASE is true ignore case
%* Like Visual Basic "INSTR".
%*
%* Syntax: instr(Posi,Targ,Key,[IgnCase])
%* Posi - Initial position of the search in the target
%* Targ - String target of the search
%* Key - String to be searched in the target
%* IngCase - TRUE if ignores case
%*
%* Example:
%* instr(5,str('Mary has a Mouse'),'m',true) % Search "m" from 5o. character
%* ans=
%* 12
%***************************************************************************
function pos=instr(posi,targ,key,igncase)
targ=char(targ);
key=char(key);
if nargin<4, igncase=false; end
if igncase
targ=upper(targ);
key=upper(key);
end
vet = strfind(targ,key);
if isempty(vet)
pos=0;
else
indices = ( find(vet>=posi));
if isempty(indices)
pos=0;
else
pos=vet(indices(1));
end
end
end % instr
%******************************************************************************
%* replace
%* replace in ORIGSTR, OLDSUBSTR for NEWSUBSTR all occurrences or a specified
%*
%* Syntax: replace(OrigStr, OldSubStr, NewSubStr, [ Pos ] )
%* OrigStr - String target of the change process
%* OldSubStr - Substring to be searched in the target
%* NewSubStr - String to be introduced in the target
%* Pos - No. of occurrence, or 'first','f'(first) or 'l','last'(last)
%*
%* Example:
%* replace(str('tea is the sea'),'ea','o','last') % replace last 'ea' occurrance for 'o'
%* ans=
%* tea is the so
%*******************************************************************************
function r=replace(origStr, oldSubstr, newSubstr, option)
if nargin<4
r = str( strrep(char(origStr),char(oldSubstr),char(newSubstr)));
return
end
r=str(origStr);
vet=strfind(origStr,oldSubstr);
if isempty(vet), return, end
if isnumeric(option)
pos=floor(option(1));
if pos<=0 || pos>length(vet), return, end
pos=vet(pos);
else
option = upper(option);
if strcmp(option,'F') || strcmp(option,'FIRST')
pos = vet(1);
elseif strcmp(option,'L') || strcmp(option,'LAST')
pos = vet(end);
else
return
end
end
origStr = char(origStr);
r = str( [ origStr(1:pos-1) char(newSubstr) origStr(pos+length(oldSubstr):end) ] );
end % replace
%*****************************************************************
%* Minus (Overload for "-")
%*
%* Syntax: a - b
%* Delete in A all occurrence of B
%*
%* Example:
%* str('dime for a crime') - 'ime'
%* ans =
%* d for a cr
%*****************************************************************
function r=minus(a,b)
r = replace(a,b,'');
end
%*****************************************************************
%* repeat
%* repeat characters in STRING for N times.
%*
%* Syntax: repeat(String, N)
%* String - String to be repeated
%* N - Number of repetitions
%*
%*****************************************************************
function r=repeat(string,n)
r=str('');
if ~ isscalar(n) || ~ isnumeric(n), return, end
string=char(string);
dest=repmat(string,1,n);
r=str(dest);
end
%*****************************************************************
%* Plus(Overload for "+")
%* Implement a + b for object str as a concatenation.
%' Accept also numbers.
%*
%* Syntax: a + b [ + ... + k + ... ]
%* K - String to be concatenated
%*
%* Example:
%* a=str('flier');
%* a + ' for a fly'
%* ans =
%* flier for a fly
%*****************************************************************
function r = plus(a, b)
if isnumeric(a), a=str(a); end
if isnumeric(b), b=str(b); end
r = str(horzcat(char(a),char(b)));
end % plus
%*****************************************************************
%* MTimes(Overload for "*")
%* Implement a * n as repeat str a, n times
%*
%* Syntax: a * N
%* a - String to be repeated
%* N - number of repetitions
%*
%* Example:
%* a=str('best! ');
%* a * 3
%* ans = best! best! best!
%*****************************************************************
function r = mtimes(a,n)
r=repeat(a,n);
end
%*****************************************************************
%* MRDivide (Overload for "/")
%* Search B in A e returns array with matching indexes
%*
%* Syntax: A / B
%* A - String target of the search
%* B - String to be searched in the target
%*
%* Example:
%* a=str('a band that bangs');
%* a / 'ba'
%* ans=
%* 3 13
%*****************************************************************
function r = mrdivide(a,b)
r=strfind(char(a),char(b));
end
%*****************************************************************
%* MLDivide (Overload for "\")
%* Search A in B e returns array with matching indexes
%*
%* Syntax: A \ B
%* A - String to be searched in the target
%* B - String target of the search
%*
%* Example:
%* a=str('a band that bangs');
%* 'ba' \ a
%* ans=
%* 3 13
%*****************************************************************
function r = mldivide(a,b)
r=strfind(char(b),char(a));
end
%*****************************************************************
%* Eq (Overload for "==")
%* Implement test for string equality.
%*
%* Syntax: a == b
%* a , b - Strings to be compared
%* igncase - true if ignores case (default false)
%*****************************************************************
function r = eq(a,b,igncase)
if nargin<3, igncase =false; end
if igncase
r = strcmpi(char(a),char(b));
else
r = strcmp(char(a),char(b));
end
end % minus
%*****************************************************************
%* Ne (Overload for "~=")
%* Implement test for string unequality.
%*
%* Syntax: a ~= b
%* a , b - Strings to be compared
%* igncase - - true if ignores case (default false)
%*****************************************************************
function r = ne(a,b,igncase)
if nargin<3, igncase =false; end
if igncase
r = ~ strcmpi(char(a),char(b));
else
r = ~ strcmp(char(a),char(b));
end
end % minus
%*****************************************************************
%* Lt (Overload for "<")
%* Implement test for string lesser than
%*
%* Syntax: a < b
%* a , b - Strings to be compared
%* igncase - true if ignores case (default false)
%*
%* Example 1:
%* str('STOCK') < 'stock'
%* ans =
%* 1 (true)
%* Example 2:
%* lt(str('STOCK'),'stock',true)
%* ans =
%* 0 (false)
%*****************************************************************
function r = lt(a,b,igncase)
if nargin<3, igncase =false; end
r = (compare_strings(a,b,igncase)<0);
end
%*****************************************************************
%* Le (Overload for "<=")
%* Implement test for string lesser or equal than
%*
%* Syntax: a <= b
%* a, b - Strings to be compared
%* igncase - true if ignores case (default false)
%*****************************************************************
function r = le(a,b, igncase)
if nargin<3, igncase =false; end
r = (compare_strings(a,b,igncase)<=0);
end
%*****************************************************************
%* Ge (Overload for ">=")
%* Implement test for string greater or equal than
%*
%* Syntax: a >= b
%* a, b - Strings to be compared
%* igncase - true if ignores case (default false)
%*****************************************************************
function r = ge(a, b, igncase)
if nargin<3, igncase =false; end
r = (compare_strings(a,b,igncase)>=0);
end
%*****************************************************************
%* Gt (Overload for ">")
%* Implement test for string greater than
%*
%* Syntax: a > b
%* a, b - Strings to be compared
%* igncase - true if ignores case (default false)
%*****************************************************************
function r = gt(a, b,igncase)
if nargin<3, igncase =false; end
r = (compare_strings(a,b,igncase)>0);
end
%*****************************************************************
%* disp (Overload)
%* Display object in MATLAB syntax
%*
%* Syntax: disp(Stri)
%* Stri - String to be listed in the Command Window
%*****************************************************************
function disp(Stri)
disp(Stri.s)
end % disp
%*****************************************************************
%* length (Overload)
%* Returns length of STRI
%*
%* Syntax: length(Stri)
%* Stri - String
%*****************************************************************
function r=length(Stri)
r = length(Stri.s);
end
%*****************************************************************
%* subsref (Overload for "()" and ".")
%* Allow direct element indexing and field selector
%*
%* Syntax: Stri(indexes) (right side)
%* Stri - String to be indexed
%* Indexes - indexed with MatLab syntax
%*
%* OR
%*
%* Syntax: Stri.s (right side)
%* Stri - String accessed with S field
%*
%* Example 1:
%* a = str('display');
%* a(4:end)
%* ans=
%* play
%*
%* Example 2:
%* a = str('display');
%* a.s
%* ans=
%* display
%*****************************************************************
function b = subsref(a,su)
if strcmp(su(1).type,'()') % The user can utilizate () for indexing
b = subsref(a.s,su);
elseif su(1).type=='.' % The user can utilizate .s for access value
if su(1).subs=='s', b = a.s; end
end
end
%*****************************************************************
%* end (Overload for "end" subscrict ) (AUX)
%* Calculates "end" subscrit at right way for STR type.
%* It's not to be used directly.
%******************************************************************
function v=end(a,~,~)
v=length(a.s);
end
%*****************************************************************
%* subsasgn (Overload for left "()" )
%* Allow direct assign element indexing
%*
%* Syntax: Stri(indexes) = ....
%* Stri - String to be indexed
%* Indexes - indexed with MatLab syntax
%* OR
%*
%* Syntax: Stri.s = ....
%* Stri - String accessed with S field
%*
%* Example 1:
%* a = str('display');
%* a(4:end) = 'able';
%* a=
%* disable
%*
%* Example 2:
%* a = str('display');
%* a.s = 'MatLab'
%* ans=
%* MatLab
%*****************************************************************
function a = subsasgn(a, su, b)
if strcmp(su(1).type,'()') % The user can utilizate () for indexing
a.s = subsasgn(a.s, su, b);
elseif su(1).type=='.'
if su(1).subs=='s', a.s = b; end
end
end
%*****************************************************************
%* horzcat (Overload for "[ ]")
%* Concatenes all arguments. Like another overload function
%* it's enough just one STR argument, as shown in the example.
%*
%* Syntax: [ Str1 Str2 ... StrK ... ]
%* StrK - Strings to be concatenated.
%*
%* Example:
%* a = ' shine ';
%* ['*' a '<' str(' light ') '>' a '*']
%* ans =
%* * shine < light > shine *
%*****************************************************************
function r=horzcat(varargin)
n = size(varargin,2);
if n==0, r=str(''); return, end
aux=varargin{1};
if isnumeric(varargin{1}), aux=str(aux); end
r = char(aux);
for ind=2:n
aux=varargin{ind};
if isnumeric(varargin{ind}), aux=str(aux); end
r =[r char(aux) ];
end
r=str(r);
end
%*****************************************************************
%* vertcat (Overload for "[ ; ]")
%* Create matrix of chars, from same length STRs and character array
%*
%* Syntax: [ Str1 ; Str2 ; ... ; StrK ; ... ]
%* StrK - Strings to be concatenated
%*****************************************************************
function r=vertcat(varargin)
n = size(varargin,2);
if n==0, r=''; return, end
r = char(varargin{1});
for ind=2:n
r=[ r ; char(varargin{ind}) ];
end
end
%*****************************************************************
%* char (Overload for "char")
%* Convert A to character array
%*
%* Syntax: char(Stri)
%* Stri - String to be converted in character array
%****************************************************************
function r=char(a)
r = a.s;
end
%*****************************************************************
%* left
%* Return N first characters from A
%*
%* Syntax: left(a,n)
%* a - String
%* N - number of character to be extracted in the left
%*****************************************************************
function r=left(a,n)
if length(a.s) < n
r = a.s;
else
r = a.s(1:n);
end
end
%*****************************************************************
%* right
%* Return N last characters from A
%*
%* Syntax: right(a,n)
%* a - String
%* N - number of character to be extracted in the right
%*****************************************************************
function r=right(a,n)
if length(a.s) < n
r = a.s;
else
r = a.s(end-n+1:end);
end
end
%*****************************************************************
%* mid
%* Return N characters from A, starting from POS
%*
%* Syntax: mid(a,Pos,[N])
%* a - String
%* Pos - position of extraction, starting from 1
%* N - number of character to be extracted
%*****************************************************************
function r=mid(a, pos,n)
if pos==0, pos=1; end
if pos>length(a.s)
r=str('');
return
end
if nargin<3
r=str(a.s(pos:end));
return
end
if pos+n-1>length(a.s)
r=str(a.s(pos:end));
return
end
r=str(a.s(pos:pos+n-1));
end
end % methods
end % classdef
%**********************************************************************
%* padcommon (AUX)
%* Auxiliar function for padding strings and padding and format numbers
%* It's not to be used directly.
%*
%* Syntax: padcommon(a,tipo,[Len CarDec] )
%* a - String
%* tipo - 1-Left, 2-Center, 3-Right
%* Len - Size of the field, if number. When number is wider, ignores it.
%* CarDec - Number of decimal digits or character to fill
%**********************************************************************
function r = padcommon(a,tipo,len,cardec)
if isa(a,'str') || isa(a,'char')
c = length(a);
if c<len
if tipo==3
r = str([ repmat(cardec,1,len-c) a ]);
elseif tipo==1
r = str([ a repmat(cardec,1,len-c) ]);
else
bef = floor((len-c)/2);
r = str([ repmat(cardec,1,bef) a repmat(cardec,1,len-c-bef) ]);
end
else
r = str(a);
end
return
end
aux = num2str(a,[ '%50.' int2str(cardec) 'f']);
if length(aux) >= len
r = str(aux);
else
c = length(aux);
if tipo==3
r = str([ blanks(len-c) aux ]);
elseif tipo==1
r = str([ aux blanks(len-c) ]);
else
bef = floor((len-c)/2);
r = str([ blanks(bef) aux blanks(len-c-bef) ]);
end
end
end % pad_common
%**********************************************************************
%* compare_strings (aux)
%* Function that returns 1 (a>b), -1 (a<b), 0(a=b)
%* It's not to be used directly.
%*
%* Syntax: compare_strings(a, b, [igncase])
%* a - String 1
%* b - String 2
%* igncase - true if ignores case
%* (Thanks, Cris Luengo - Oct-5-2010)
%**********************************************************************
function r = compare_strings(a,b,igncase)
% returns: 0 == equal
% 1 == a is larger
% -1 == b is larger
if nargin<3, igncase=false; end
a = str(a); a = a.s;
b = str(b); b = b.s;
if igncase
a=upper(a);
b=upper(b);
end
la = length(a);
lb = length(b);
len = min(la,lb);
r = a(1:len)-b(1:len);
[~,~,r] = find(r,1,'first'); % find first non-zero value
if ~isempty(r)
r = sign(r);
else % they're equal, compare lengths
if la==lb
r = 0;
elseif la<lb
r = -1;
else
r = 1;
end
end
end % compare_string